blob: ce10d1bea0d6d09d4a9013bfd9983ab2b1bfb63e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500110#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500111#undef HAVE_SCHED_SETAFFINITY
112#endif
113
Benjamin Peterson9428d532011-09-14 11:45:52 -0400114#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
115#define USE_XATTRS
116#endif
117
118#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400119#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400120#endif
121
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
123#ifdef HAVE_SYS_SOCKET_H
124#include <sys/socket.h>
125#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000126#endif
127
Victor Stinner8b905bd2011-10-25 13:34:04 +0200128#ifdef HAVE_DLFCN_H
129#include <dlfcn.h>
130#endif
131
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100132#if defined(MS_WINDOWS)
133# define TERMSIZE_USE_CONIO
134#elif defined(HAVE_SYS_IOCTL_H)
135# include <sys/ioctl.h>
136# if defined(HAVE_TERMIOS_H)
137# include <termios.h>
138# endif
139# if defined(TIOCGWINSZ)
140# define TERMSIZE_USE_IOCTL
141# endif
142#endif /* MS_WINDOWS */
143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000145/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_GETCWD 1
151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#if defined(__OS2__)
154#define HAVE_EXECV 1
155#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#include <process.h>
158#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#define HAVE_EXECV 1
161#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_OPENDIR 1
163#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000164#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_WAIT 1
166#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000168#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000169#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000170#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000171#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_EXECV 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
175#define HAVE_CWAIT 1
176#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000177#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000178#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000179#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
180/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182/* Unix functions that the configure script doesn't check for */
183#define HAVE_EXECV 1
184#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000185#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000186#define HAVE_FORK1 1
187#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#define HAVE_GETCWD 1
189#define HAVE_GETEGID 1
190#define HAVE_GETEUID 1
191#define HAVE_GETGID 1
192#define HAVE_GETPPID 1
193#define HAVE_GETUID 1
194#define HAVE_KILL 1
195#define HAVE_OPENDIR 1
196#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000197#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000199#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000200#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif /* _MSC_VER */
202#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000205
Victor Stinnera2f7c002012-02-08 03:36:25 +0100206
207
208
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000211#if defined(__sgi)&&_COMPILER_VERSION>=700
212/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
213 (default) */
214extern char *ctermid_r(char *);
215#endif
216
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000217#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000218#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000220#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000221#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
227#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int chdir(char *);
229extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000230#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(const char *);
232extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000234#ifdef __BORLANDC__
235extern int chmod(const char *, int);
236#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000238#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000239/*#ifdef HAVE_FCHMOD
240extern int fchmod(int, mode_t);
241#endif*/
242/*#ifdef HAVE_LCHMOD
243extern int lchmod(const char *, mode_t);
244#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int chown(const char *, uid_t, gid_t);
246extern char *getcwd(char *, int);
247extern char *strerror(int);
248extern int link(const char *, const char *);
249extern int rename(const char *, const char *);
250extern int stat(const char *, struct stat *);
251extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000253extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000254#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000259
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#ifdef HAVE_UTIME_H
263#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000264#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000266#ifdef HAVE_SYS_UTIME_H
267#include <sys/utime.h>
268#define HAVE_UTIME_H /* pretend we do for the rest of this file */
269#endif /* HAVE_SYS_UTIME_H */
270
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#ifdef HAVE_SYS_TIMES_H
272#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000273#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274
275#ifdef HAVE_SYS_PARAM_H
276#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000277#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
279#ifdef HAVE_SYS_UTSNAME_H
280#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#define NAMLEN(dirent) strlen((dirent)->d_name)
286#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#include <direct.h>
289#define NAMLEN(dirent) strlen((dirent)->d_name)
290#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000292#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000294#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000296#endif
297#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000306#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000308#endif
309#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000315#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000316#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000317#endif
318#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000325#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000327#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000328#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000329#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
330#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000331static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000332#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000333#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000334
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000336#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000337#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Tim Petersbc2e10e2002-03-03 23:17:02 +0000339#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340#if defined(PATH_MAX) && PATH_MAX > 1024
341#define MAXPATHLEN PATH_MAX
342#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000343#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000344#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000345#endif /* MAXPATHLEN */
346
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#ifdef UNION_WAIT
348/* Emulate some macros on systems that have a union instead of macros */
349
350#ifndef WIFEXITED
351#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
352#endif
353
354#ifndef WEXITSTATUS
355#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
356#endif
357
358#ifndef WTERMSIG
359#define WTERMSIG(u_wait) ((u_wait).w_termsig)
360#endif
361
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362#define WAIT_TYPE union wait
363#define WAIT_STATUS_INT(s) (s.w_status)
364
365#else /* !UNION_WAIT */
366#define WAIT_TYPE int
367#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000368#endif /* UNION_WAIT */
369
Greg Wardb48bc172000-03-01 21:51:56 +0000370/* Don't use the "_r" form if we don't need it (also, won't have a
371 prototype for it, at least on Solaris -- maybe others as well?). */
372#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
373#define USE_CTERMID_R
374#endif
375
Fred Drake699f3522000-06-29 21:12:41 +0000376/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000377#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000378#undef FSTAT
379#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000380#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000381# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700382# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000383# define FSTAT win32_fstat
384# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000385#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000386# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700387# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000388# define FSTAT fstat
389# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000390#endif
391
Tim Peters11b23062003-04-23 02:39:17 +0000392#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000393#include <sys/mkdev.h>
394#else
395#if defined(MAJOR_IN_SYSMACROS)
396#include <sys/sysmacros.h>
397#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000398#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
399#include <sys/mkdev.h>
400#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000401#endif
Fred Drake699f3522000-06-29 21:12:41 +0000402
Larry Hastings9cf065c2012-06-22 16:30:09 -0700403
404#ifdef MS_WINDOWS
405static int
406win32_warn_bytes_api()
407{
408 return PyErr_WarnEx(PyExc_DeprecationWarning,
409 "The Windows bytes API has been deprecated, "
410 "use Unicode filenames instead",
411 1);
412}
413#endif
414
415
416#ifdef AT_FDCWD
417#define DEFAULT_DIR_FD AT_FDCWD
418#else
419#define DEFAULT_DIR_FD (-100)
420#endif
421
422static int
423_fd_converter(PyObject *o, int *p, int default_value) {
424 long long_value;
425 if (o == Py_None) {
426 *p = default_value;
427 return 1;
428 }
429 if (PyFloat_Check(o)) {
430 PyErr_SetString(PyExc_TypeError,
431 "integer argument expected, got float" );
432 return 0;
433 }
434 long_value = PyLong_AsLong(o);
435 if (long_value == -1 && PyErr_Occurred())
436 return 0;
437 if (long_value > INT_MAX) {
438 PyErr_SetString(PyExc_OverflowError,
439 "signed integer is greater than maximum");
440 return 0;
441 }
442 if (long_value < INT_MIN) {
443 PyErr_SetString(PyExc_OverflowError,
444 "signed integer is less than minimum");
445 return 0;
446 }
447 *p = (int)long_value;
448 return 1;
449}
450
451static int
452dir_fd_converter(PyObject *o, void *p) {
453 return _fd_converter(o, (int *)p, DEFAULT_DIR_FD);
454}
455
456
457
458/*
459 * A PyArg_ParseTuple "converter" function
460 * that handles filesystem paths in the manner
461 * preferred by the os module.
462 *
463 * path_converter accepts (Unicode) strings and their
464 * subclasses, and bytes and their subclasses. What
465 * it does with the argument depends on the platform:
466 *
467 * * On Windows, if we get a (Unicode) string we
468 * extract the wchar_t * and return it; if we get
469 * bytes we extract the char * and return that.
470 *
471 * * On all other platforms, strings are encoded
472 * to bytes using PyUnicode_FSConverter, then we
473 * extract the char * from the bytes object and
474 * return that.
475 *
476 * path_converter also optionally accepts signed
477 * integers (representing open file descriptors) instead
478 * of path strings.
479 *
480 * Input fields:
481 * path.nullable
482 * If nonzero, the path is permitted to be None.
483 * path.allow_fd
484 * If nonzero, the path is permitted to be a file handle
485 * (a signed int) instead of a string.
486 * path.function_name
487 * If non-NULL, path_converter will use that as the name
488 * of the function in error messages.
489 * (If path.argument_name is NULL it omits the function name.)
490 * path.argument_name
491 * If non-NULL, path_converter will use that as the name
492 * of the parameter in error messages.
493 * (If path.argument_name is NULL it uses "path".)
494 *
495 * Output fields:
496 * path.wide
497 * Points to the path if it was expressed as Unicode
498 * and was not encoded. (Only used on Windows.)
499 * path.narrow
500 * Points to the path if it was expressed as bytes,
501 * or it was Unicode and was encoded to bytes.
502 * path.fd
503 * Contains a file descriptor if path.accept_fd was true
504 * and the caller provided a signed integer instead of any
505 * sort of string.
506 *
507 * WARNING: if your "path" parameter is optional, and is
508 * unspecified, path_converter will never get called.
509 * So if you set allow_fd, you *MUST* initialize path.fd = -1
510 * yourself!
511 * path.length
512 * The length of the path in characters, if specified as
513 * a string.
514 * path.object
515 * The original object passed in.
516 * path.cleanup
517 * For internal use only. May point to a temporary object.
518 * (Pay no attention to the man behind the curtain.)
519 *
520 * At most one of path.wide or path.narrow will be non-NULL.
521 * If path was None and path.nullable was set,
522 * or if path was an integer and path.allow_fd was set,
523 * both path.wide and path.narrow will be NULL
524 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200525 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700526 * path_converter takes care to not write to the path_t
527 * unless it's successful. However it must reset the
528 * "cleanup" field each time it's called.
529 *
530 * Use as follows:
531 * path_t path;
532 * memset(&path, 0, sizeof(path));
533 * PyArg_ParseTuple(args, "O&", path_converter, &path);
534 * // ... use values from path ...
535 * path_cleanup(&path);
536 *
537 * (Note that if PyArg_Parse fails you don't need to call
538 * path_cleanup(). However it is safe to do so.)
539 */
540typedef struct {
541 char *function_name;
542 char *argument_name;
543 int nullable;
544 int allow_fd;
545 wchar_t *wide;
546 char *narrow;
547 int fd;
548 Py_ssize_t length;
549 PyObject *object;
550 PyObject *cleanup;
551} path_t;
552
553static void
554path_cleanup(path_t *path) {
555 if (path->cleanup) {
556 Py_DECREF(path->cleanup);
557 path->cleanup = NULL;
558 }
559}
560
561static int
562path_converter(PyObject *o, void *p) {
563 path_t *path = (path_t *)p;
564 PyObject *unicode, *bytes;
565 Py_ssize_t length;
566 char *narrow;
567
568#define FORMAT_EXCEPTION(exc, fmt) \
569 PyErr_Format(exc, "%s%s" fmt, \
570 path->function_name ? path->function_name : "", \
571 path->function_name ? ": " : "", \
572 path->argument_name ? path->argument_name : "path")
573
574 /* Py_CLEANUP_SUPPORTED support */
575 if (o == NULL) {
576 path_cleanup(path);
577 return 1;
578 }
579
580 /* ensure it's always safe to call path_cleanup() */
581 path->cleanup = NULL;
582
583 if (o == Py_None) {
584 if (!path->nullable) {
585 FORMAT_EXCEPTION(PyExc_TypeError,
586 "can't specify None for %s argument");
587 return 0;
588 }
589 path->wide = NULL;
590 path->narrow = NULL;
591 path->length = 0;
592 path->object = o;
593 path->fd = -1;
594 return 1;
595 }
596
597 unicode = PyUnicode_FromObject(o);
598 if (unicode) {
599#ifdef MS_WINDOWS
600 wchar_t *wide;
601 length = PyUnicode_GET_SIZE(unicode);
602 if (length > 32767) {
603 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
604 Py_DECREF(unicode);
605 return 0;
606 }
607
608 wide = PyUnicode_AsUnicode(unicode);
609 if (!wide) {
610 Py_DECREF(unicode);
611 return 0;
612 }
613
614 path->wide = wide;
615 path->narrow = NULL;
616 path->length = length;
617 path->object = o;
618 path->fd = -1;
619 path->cleanup = unicode;
620 return Py_CLEANUP_SUPPORTED;
621#else
622 int converted = PyUnicode_FSConverter(unicode, &bytes);
623 Py_DECREF(unicode);
624 if (!converted)
625 bytes = NULL;
626#endif
627 }
628 else {
629 PyErr_Clear();
630 bytes = PyBytes_FromObject(o);
631 if (!bytes) {
632 PyErr_Clear();
633 if (path->allow_fd) {
634 int fd;
635 /*
636 * note: _fd_converter always permits None.
637 * but we've already done our None check.
638 * so o cannot be None at this point.
639 */
640 int result = _fd_converter(o, &fd, -1);
641 if (result) {
642 path->wide = NULL;
643 path->narrow = NULL;
644 path->length = 0;
645 path->object = o;
646 path->fd = fd;
647 return result;
648 }
649 }
650 }
651 }
652
653 if (!bytes) {
654 if (!PyErr_Occurred())
655 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
656 return 0;
657 }
658
659#ifdef MS_WINDOWS
660 if (win32_warn_bytes_api()) {
661 Py_DECREF(bytes);
662 return 0;
663 }
664#endif
665
666 length = PyBytes_GET_SIZE(bytes);
667#ifdef MS_WINDOWS
668 if (length > MAX_PATH) {
669 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
670 Py_DECREF(bytes);
671 return 0;
672 }
673#endif
674
675 narrow = PyBytes_AS_STRING(bytes);
676 if (length != strlen(narrow)) {
677 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
678 Py_DECREF(bytes);
679 return 0;
680 }
681
682 path->wide = NULL;
683 path->narrow = narrow;
684 path->length = length;
685 path->object = o;
686 path->fd = -1;
687 path->cleanup = bytes;
688 return Py_CLEANUP_SUPPORTED;
689}
690
691static void
692argument_unavailable_error(char *function_name, char *argument_name) {
693 PyErr_Format(PyExc_NotImplementedError,
694 "%s%s%s unavailable on this platform",
695 (function_name != NULL) ? function_name : "",
696 (function_name != NULL) ? ": ": "",
697 argument_name);
698}
699
700static int
701dir_fd_unavailable(PyObject *o, void *p) {
702 int *dir_fd = (int *)p;
703 int return_value = _fd_converter(o, dir_fd, DEFAULT_DIR_FD);
704 if (!return_value)
705 return 0;
706 if (*dir_fd == DEFAULT_DIR_FD)
707 return 1;
708 argument_unavailable_error(NULL, "dir_fd");
709 return 0;
710}
711
712static int
713fd_specified(char *function_name, int fd) {
714 if (fd == -1)
715 return 0;
716
717 argument_unavailable_error(function_name, "fd");
718 return 1;
719}
720
721static int
722follow_symlinks_specified(char *function_name, int follow_symlinks) {
723 if (follow_symlinks)
724 return 0;
725
726 argument_unavailable_error(function_name, "follow_symlinks");
727 return 1;
728}
729
730static int
731path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
732 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
733 PyErr_Format(PyExc_ValueError,
734 "%s: can't specify dir_fd without matching path",
735 function_name);
736 return 1;
737 }
738 return 0;
739}
740
741static int
742dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
743 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
744 PyErr_Format(PyExc_ValueError,
745 "%s: can't specify both dir_fd and fd",
746 function_name);
747 return 1;
748 }
749 return 0;
750}
751
752static int
753fd_and_follow_symlinks_invalid(char *function_name, int fd,
754 int follow_symlinks) {
755 if ((fd > 0) && (!follow_symlinks)) {
756 PyErr_Format(PyExc_ValueError,
757 "%s: cannot use fd and follow_symlinks together",
758 function_name);
759 return 1;
760 }
761 return 0;
762}
763
764static int
765dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
766 int follow_symlinks) {
767 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
768 PyErr_Format(PyExc_ValueError,
769 "%s: cannot use dir_fd and follow_symlinks together",
770 function_name);
771 return 1;
772 }
773 return 0;
774}
775
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200776/* A helper used by a number of POSIX-only functions */
777#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000778static int
779_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000780{
781#if !defined(HAVE_LARGEFILE_SUPPORT)
782 *((off_t*)addr) = PyLong_AsLong(arg);
783#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000784 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000785#endif
786 if (PyErr_Occurred())
787 return 0;
788 return 1;
789}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200790#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000791
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000792#if defined _MSC_VER && _MSC_VER >= 1400
793/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
794 * valid and throw an assertion if it isn't.
795 * Normally, an invalid fd is likely to be a C program error and therefore
796 * an assertion can be useful, but it does contradict the POSIX standard
797 * which for write(2) states:
798 * "Otherwise, -1 shall be returned and errno set to indicate the error."
799 * "[EBADF] The fildes argument is not a valid file descriptor open for
800 * writing."
801 * Furthermore, python allows the user to enter any old integer
802 * as a fd and should merely raise a python exception on error.
803 * The Microsoft CRT doesn't provide an official way to check for the
804 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000805 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000806 * internal structures involved.
807 * The structures below must be updated for each version of visual studio
808 * according to the file internal.h in the CRT source, until MS comes
809 * up with a less hacky way to do this.
810 * (all of this is to avoid globally modifying the CRT behaviour using
811 * _set_invalid_parameter_handler() and _CrtSetReportMode())
812 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000813/* The actual size of the structure is determined at runtime.
814 * Only the first items must be present.
815 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000816typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000817 intptr_t osfhnd;
818 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000819} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000820
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000821extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000822#define IOINFO_L2E 5
823#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
824#define IOINFO_ARRAYS 64
825#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
826#define FOPEN 0x01
827#define _NO_CONSOLE_FILENO (intptr_t)-2
828
829/* This function emulates what the windows CRT does to validate file handles */
830int
831_PyVerify_fd(int fd)
832{
Victor Stinner8c62be82010-05-06 00:08:46 +0000833 const int i1 = fd >> IOINFO_L2E;
834 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000835
Antoine Pitrou22e41552010-08-15 18:07:50 +0000836 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000837
Victor Stinner8c62be82010-05-06 00:08:46 +0000838 /* Determine the actual size of the ioinfo structure,
839 * as used by the CRT loaded in memory
840 */
841 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
842 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
843 }
844 if (sizeof_ioinfo == 0) {
845 /* This should not happen... */
846 goto fail;
847 }
848
849 /* See that it isn't a special CLEAR fileno */
850 if (fd != _NO_CONSOLE_FILENO) {
851 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
852 * we check pointer validity and other info
853 */
854 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
855 /* finally, check that the file is open */
856 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
857 if (info->osfile & FOPEN) {
858 return 1;
859 }
860 }
861 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000862 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000863 errno = EBADF;
864 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000865}
866
867/* the special case of checking dup2. The target fd must be in a sensible range */
868static int
869_PyVerify_fd_dup2(int fd1, int fd2)
870{
Victor Stinner8c62be82010-05-06 00:08:46 +0000871 if (!_PyVerify_fd(fd1))
872 return 0;
873 if (fd2 == _NO_CONSOLE_FILENO)
874 return 0;
875 if ((unsigned)fd2 < _NHANDLE_)
876 return 1;
877 else
878 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000879}
880#else
881/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
882#define _PyVerify_fd_dup2(A, B) (1)
883#endif
884
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000885#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000886/* The following structure was copied from
887 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
888 include doesn't seem to be present in the Windows SDK (at least as included
889 with Visual Studio Express). */
890typedef struct _REPARSE_DATA_BUFFER {
891 ULONG ReparseTag;
892 USHORT ReparseDataLength;
893 USHORT Reserved;
894 union {
895 struct {
896 USHORT SubstituteNameOffset;
897 USHORT SubstituteNameLength;
898 USHORT PrintNameOffset;
899 USHORT PrintNameLength;
900 ULONG Flags;
901 WCHAR PathBuffer[1];
902 } SymbolicLinkReparseBuffer;
903
904 struct {
905 USHORT SubstituteNameOffset;
906 USHORT SubstituteNameLength;
907 USHORT PrintNameOffset;
908 USHORT PrintNameLength;
909 WCHAR PathBuffer[1];
910 } MountPointReparseBuffer;
911
912 struct {
913 UCHAR DataBuffer[1];
914 } GenericReparseBuffer;
915 };
916} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
917
918#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
919 GenericReparseBuffer)
920#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
921
922static int
Brian Curtind25aef52011-06-13 15:16:04 -0500923win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000924{
925 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
926 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
927 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000928
929 if (0 == DeviceIoControl(
930 reparse_point_handle,
931 FSCTL_GET_REPARSE_POINT,
932 NULL, 0, /* in buffer */
933 target_buffer, sizeof(target_buffer),
934 &n_bytes_returned,
935 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500936 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000937
938 if (reparse_tag)
939 *reparse_tag = rdb->ReparseTag;
940
Brian Curtind25aef52011-06-13 15:16:04 -0500941 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000942}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100943
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000944#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000945
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000947#ifdef WITH_NEXT_FRAMEWORK
948/* On Darwin/MacOSX a shared library or framework has no access to
949** environ directly, we must obtain it with _NSGetEnviron().
950*/
951#include <crt_externs.h>
952static char **environ;
953#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000954extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000955#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000956
Barry Warsaw53699e91996-12-10 23:23:01 +0000957static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000958convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000959{
Victor Stinner8c62be82010-05-06 00:08:46 +0000960 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000961#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000962 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000963#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000964 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000965#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000966#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000967 APIRET rc;
968 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
969#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000970
Victor Stinner8c62be82010-05-06 00:08:46 +0000971 d = PyDict_New();
972 if (d == NULL)
973 return NULL;
974#ifdef WITH_NEXT_FRAMEWORK
975 if (environ == NULL)
976 environ = *_NSGetEnviron();
977#endif
978#ifdef MS_WINDOWS
979 /* _wenviron must be initialized in this way if the program is started
980 through main() instead of wmain(). */
981 _wgetenv(L"");
982 if (_wenviron == NULL)
983 return d;
984 /* This part ignores errors */
985 for (e = _wenviron; *e != NULL; e++) {
986 PyObject *k;
987 PyObject *v;
988 wchar_t *p = wcschr(*e, L'=');
989 if (p == NULL)
990 continue;
991 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
992 if (k == NULL) {
993 PyErr_Clear();
994 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000995 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000996 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
997 if (v == NULL) {
998 PyErr_Clear();
999 Py_DECREF(k);
1000 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001001 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 if (PyDict_GetItem(d, k) == NULL) {
1003 if (PyDict_SetItem(d, k, v) != 0)
1004 PyErr_Clear();
1005 }
1006 Py_DECREF(k);
1007 Py_DECREF(v);
1008 }
1009#else
1010 if (environ == NULL)
1011 return d;
1012 /* This part ignores errors */
1013 for (e = environ; *e != NULL; e++) {
1014 PyObject *k;
1015 PyObject *v;
1016 char *p = strchr(*e, '=');
1017 if (p == NULL)
1018 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001019 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001020 if (k == NULL) {
1021 PyErr_Clear();
1022 continue;
1023 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001024 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001025 if (v == NULL) {
1026 PyErr_Clear();
1027 Py_DECREF(k);
1028 continue;
1029 }
1030 if (PyDict_GetItem(d, k) == NULL) {
1031 if (PyDict_SetItem(d, k, v) != 0)
1032 PyErr_Clear();
1033 }
1034 Py_DECREF(k);
1035 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001036 }
1037#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001038#if defined(PYOS_OS2)
1039 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1040 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1041 PyObject *v = PyBytes_FromString(buffer);
1042 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1043 Py_DECREF(v);
1044 }
1045 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1046 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1047 PyObject *v = PyBytes_FromString(buffer);
1048 PyDict_SetItemString(d, "ENDLIBPATH", v);
1049 Py_DECREF(v);
1050 }
1051#endif
1052 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001053}
1054
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001055/* Set a POSIX-specific error from errno, and return NULL */
1056
Barry Warsawd58d7641998-07-23 16:14:40 +00001057static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001058posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001059{
Victor Stinner8c62be82010-05-06 00:08:46 +00001060 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061}
Barry Warsawd58d7641998-07-23 16:14:40 +00001062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001063posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001066}
1067
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001068
Mark Hammondef8b6542001-05-13 08:04:26 +00001069static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001070posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001071{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001072 PyObject *name_str, *rc;
1073 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1074 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001075 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001076 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1077 name_str);
1078 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001079 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001080}
1081
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001082#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001083static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001084win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001085{
Victor Stinner8c62be82010-05-06 00:08:46 +00001086 /* XXX We should pass the function name along in the future.
1087 (winreg.c also wants to pass the function name.)
1088 This would however require an additional param to the
1089 Windows error object, which is non-trivial.
1090 */
1091 errno = GetLastError();
1092 if (filename)
1093 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1094 else
1095 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001096}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001097
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001098static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001099win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001100{
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 /* XXX - see win32_error for comments on 'function' */
1102 errno = GetLastError();
1103 if (filename)
1104 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1105 else
1106 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001107}
1108
Victor Stinnereb5657a2011-09-30 01:44:27 +02001109static PyObject *
1110win32_error_object(char* function, PyObject* filename)
1111{
1112 /* XXX - see win32_error for comments on 'function' */
1113 errno = GetLastError();
1114 if (filename)
1115 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1116 PyExc_WindowsError,
1117 errno,
1118 filename);
1119 else
1120 return PyErr_SetFromWindowsErr(errno);
1121}
1122
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001123#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124
Larry Hastings9cf065c2012-06-22 16:30:09 -07001125/*
1126 * Some functions return Win32 errors, others only ever use posix_error
1127 * (this is for backwards compatibility with exceptions)
1128 */
1129static PyObject *
1130path_posix_error(char *function_name, path_t *path)
1131{
1132 if (path->narrow)
1133 return posix_error_with_filename(path->narrow);
1134 return posix_error();
1135}
1136
1137static PyObject *
1138path_error(char *function_name, path_t *path)
1139{
1140#ifdef MS_WINDOWS
1141 if (path->narrow)
1142 return win32_error(function_name, path->narrow);
1143 if (path->wide)
1144 return win32_error_unicode(function_name, path->wide);
1145 return win32_error(function_name, NULL);
1146#else
1147 return path_posix_error(function_name, path);
1148#endif
1149}
1150
Guido van Rossumd48f2521997-12-05 22:19:34 +00001151#if defined(PYOS_OS2)
1152/**********************************************************************
1153 * Helper Function to Trim and Format OS/2 Messages
1154 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001155static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001156os2_formatmsg(char *msgbuf, int msglen, char *reason)
1157{
1158 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1159
1160 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1161 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1162
Neal Norwitz30b5c5d2005-12-19 06:05:18 +00001163 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001164 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1165 }
1166
1167 /* Add Optional Reason Text */
1168 if (reason) {
1169 strcat(msgbuf, " : ");
1170 strcat(msgbuf, reason);
1171 }
1172}
1173
1174/**********************************************************************
1175 * Decode an OS/2 Operating System Error Code
1176 *
1177 * A convenience function to lookup an OS/2 error code and return a
1178 * text message we can use to raise a Python exception.
1179 *
1180 * Notes:
1181 * The messages for errors returned from the OS/2 kernel reside in
1182 * the file OSO001.MSG in the \OS2 directory hierarchy.
1183 *
1184 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001185static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001186os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1187{
1188 APIRET rc;
1189 ULONG msglen;
1190
1191 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1192 Py_BEGIN_ALLOW_THREADS
1193 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1194 errorcode, "oso001.msg", &msglen);
1195 Py_END_ALLOW_THREADS
1196
1197 if (rc == NO_ERROR)
1198 os2_formatmsg(msgbuf, msglen, reason);
1199 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001200 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001201 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001202
1203 return msgbuf;
1204}
1205
1206/* Set an OS/2-specific error and return NULL. OS/2 kernel
1207 errors are not in a global variable e.g. 'errno' nor are
1208 they congruent with posix error numbers. */
1209
Victor Stinner8c62be82010-05-06 00:08:46 +00001210static PyObject *
1211os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001212{
1213 char text[1024];
1214 PyObject *v;
1215
1216 os2_strerror(text, sizeof(text), code, "");
1217
1218 v = Py_BuildValue("(is)", code, text);
1219 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001220 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001221 Py_DECREF(v);
1222 }
1223 return NULL; /* Signal to Python that an Exception is Pending */
1224}
1225
1226#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001227
1228/* POSIX generic methods */
1229
Barry Warsaw53699e91996-12-10 23:23:01 +00001230static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001231posix_fildes(PyObject *fdobj, int (*func)(int))
1232{
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 int fd;
1234 int res;
1235 fd = PyObject_AsFileDescriptor(fdobj);
1236 if (fd < 0)
1237 return NULL;
1238 if (!_PyVerify_fd(fd))
1239 return posix_error();
1240 Py_BEGIN_ALLOW_THREADS
1241 res = (*func)(fd);
1242 Py_END_ALLOW_THREADS
1243 if (res < 0)
1244 return posix_error();
1245 Py_INCREF(Py_None);
1246 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001247}
Guido van Rossum21142a01999-01-08 21:05:37 +00001248
1249static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001250posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251{
Victor Stinner8c62be82010-05-06 00:08:46 +00001252 PyObject *opath1 = NULL;
1253 char *path1;
1254 int res;
1255 if (!PyArg_ParseTuple(args, format,
1256 PyUnicode_FSConverter, &opath1))
1257 return NULL;
1258 path1 = PyBytes_AsString(opath1);
1259 Py_BEGIN_ALLOW_THREADS
1260 res = (*func)(path1);
1261 Py_END_ALLOW_THREADS
1262 if (res < 0)
1263 return posix_error_with_allocated_filename(opath1);
1264 Py_DECREF(opath1);
1265 Py_INCREF(Py_None);
1266 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001270#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001272win32_1str(PyObject* args, char* func,
1273 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1274 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001275{
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001277 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001279
Victor Stinnereb5657a2011-09-30 01:44:27 +02001280 if (PyArg_ParseTuple(args, wformat, &uni))
1281 {
1282 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1283 if (wstr == NULL)
1284 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001285 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001286 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001287 Py_END_ALLOW_THREADS
1288 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001289 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 Py_INCREF(Py_None);
1291 return Py_None;
1292 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001293 PyErr_Clear();
1294
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 if (!PyArg_ParseTuple(args, format, &ansi))
1296 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001297 if (win32_warn_bytes_api())
1298 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 Py_BEGIN_ALLOW_THREADS
1300 result = funcA(ansi);
1301 Py_END_ALLOW_THREADS
1302 if (!result)
1303 return win32_error(func, ansi);
1304 Py_INCREF(Py_None);
1305 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001306
1307}
1308
1309/* This is a reimplementation of the C library's chdir function,
1310 but one that produces Win32 errors instead of DOS error codes.
1311 chdir is essentially a wrapper around SetCurrentDirectory; however,
1312 it also needs to set "magic" environment variables indicating
1313 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001314static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315win32_chdir(LPCSTR path)
1316{
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 char new_path[MAX_PATH+1];
1318 int result;
1319 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320
Victor Stinner8c62be82010-05-06 00:08:46 +00001321 if(!SetCurrentDirectoryA(path))
1322 return FALSE;
1323 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1324 if (!result)
1325 return FALSE;
1326 /* In the ANSI API, there should not be any paths longer
1327 than MAX_PATH. */
1328 assert(result <= MAX_PATH+1);
1329 if (strncmp(new_path, "\\\\", 2) == 0 ||
1330 strncmp(new_path, "//", 2) == 0)
1331 /* UNC path, nothing to do. */
1332 return TRUE;
1333 env[1] = new_path[0];
1334 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335}
1336
1337/* The Unicode version differs from the ANSI version
1338 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001339static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340win32_wchdir(LPCWSTR path)
1341{
Victor Stinner8c62be82010-05-06 00:08:46 +00001342 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1343 int result;
1344 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345
Victor Stinner8c62be82010-05-06 00:08:46 +00001346 if(!SetCurrentDirectoryW(path))
1347 return FALSE;
1348 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1349 if (!result)
1350 return FALSE;
1351 if (result > MAX_PATH+1) {
1352 new_path = malloc(result * sizeof(wchar_t));
1353 if (!new_path) {
1354 SetLastError(ERROR_OUTOFMEMORY);
1355 return FALSE;
1356 }
1357 result = GetCurrentDirectoryW(result, new_path);
1358 if (!result) {
1359 free(new_path);
1360 return FALSE;
1361 }
1362 }
1363 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1364 wcsncmp(new_path, L"//", 2) == 0)
1365 /* UNC path, nothing to do. */
1366 return TRUE;
1367 env[1] = new_path[0];
1368 result = SetEnvironmentVariableW(env, new_path);
1369 if (new_path != _new_path)
1370 free(new_path);
1371 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001372}
1373#endif
1374
Martin v. Löwis14694662006-02-03 12:54:16 +00001375#ifdef MS_WINDOWS
1376/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1377 - time stamps are restricted to second resolution
1378 - file modification times suffer from forth-and-back conversions between
1379 UTC and local time
1380 Therefore, we implement our own stat, based on the Win32 API directly.
1381*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001382#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001383
1384struct win32_stat{
1385 int st_dev;
1386 __int64 st_ino;
1387 unsigned short st_mode;
1388 int st_nlink;
1389 int st_uid;
1390 int st_gid;
1391 int st_rdev;
1392 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001393 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001394 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001395 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001396 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001397 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001398 int st_ctime_nsec;
1399};
1400
1401static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1402
1403static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001404FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001405{
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1407 /* Cannot simply cast and dereference in_ptr,
1408 since it might not be aligned properly */
1409 __int64 in;
1410 memcpy(&in, in_ptr, sizeof(in));
1411 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001412 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001413}
1414
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001416time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417{
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 /* XXX endianness */
1419 __int64 out;
1420 out = time_in + secs_between_epochs;
1421 out = out * 10000000 + nsec_in / 100;
1422 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001423}
1424
Martin v. Löwis14694662006-02-03 12:54:16 +00001425/* Below, we *know* that ugo+r is 0444 */
1426#if _S_IREAD != 0400
1427#error Unsupported C library
1428#endif
1429static int
1430attributes_to_mode(DWORD attr)
1431{
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 int m = 0;
1433 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1434 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1435 else
1436 m |= _S_IFREG;
1437 if (attr & FILE_ATTRIBUTE_READONLY)
1438 m |= 0444;
1439 else
1440 m |= 0666;
1441 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001442}
1443
1444static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001445attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001446{
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 memset(result, 0, sizeof(*result));
1448 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1449 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1450 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1451 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1452 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001453 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001454 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001455 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1456 /* first clear the S_IFMT bits */
1457 result->st_mode ^= (result->st_mode & 0170000);
1458 /* now set the bits that make this a symlink */
1459 result->st_mode |= 0120000;
1460 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001461
Victor Stinner8c62be82010-05-06 00:08:46 +00001462 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001463}
1464
Guido van Rossumd8faa362007-04-27 19:54:29 +00001465static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001466attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001467{
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 HANDLE hFindFile;
1469 WIN32_FIND_DATAA FileData;
1470 hFindFile = FindFirstFileA(pszFile, &FileData);
1471 if (hFindFile == INVALID_HANDLE_VALUE)
1472 return FALSE;
1473 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001474 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001475 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001476 info->dwFileAttributes = FileData.dwFileAttributes;
1477 info->ftCreationTime = FileData.ftCreationTime;
1478 info->ftLastAccessTime = FileData.ftLastAccessTime;
1479 info->ftLastWriteTime = FileData.ftLastWriteTime;
1480 info->nFileSizeHigh = FileData.nFileSizeHigh;
1481 info->nFileSizeLow = FileData.nFileSizeLow;
1482/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001483 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1484 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001485 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001486}
1487
1488static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001490{
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 HANDLE hFindFile;
1492 WIN32_FIND_DATAW FileData;
1493 hFindFile = FindFirstFileW(pszFile, &FileData);
1494 if (hFindFile == INVALID_HANDLE_VALUE)
1495 return FALSE;
1496 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001497 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001498 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001499 info->dwFileAttributes = FileData.dwFileAttributes;
1500 info->ftCreationTime = FileData.ftCreationTime;
1501 info->ftLastAccessTime = FileData.ftLastAccessTime;
1502 info->ftLastWriteTime = FileData.ftLastWriteTime;
1503 info->nFileSizeHigh = FileData.nFileSizeHigh;
1504 info->nFileSizeLow = FileData.nFileSizeLow;
1505/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001506 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1507 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001508 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001509}
1510
Brian Curtind25aef52011-06-13 15:16:04 -05001511/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1512static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001513static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1514 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515static int
Brian Curtind25aef52011-06-13 15:16:04 -05001516check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001517{
Brian Curtind25aef52011-06-13 15:16:04 -05001518 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001519 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1520 DWORD);
1521
Brian Curtind25aef52011-06-13 15:16:04 -05001522 /* only recheck */
1523 if (!has_GetFinalPathNameByHandle)
1524 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001525 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001526 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1527 "GetFinalPathNameByHandleA");
1528 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1529 "GetFinalPathNameByHandleW");
1530 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1531 Py_GetFinalPathNameByHandleW;
1532 }
1533 return has_GetFinalPathNameByHandle;
1534}
1535
1536static BOOL
1537get_target_path(HANDLE hdl, wchar_t **target_path)
1538{
1539 int buf_size, result_length;
1540 wchar_t *buf;
1541
1542 /* We have a good handle to the target, use it to determine
1543 the target path name (then we'll call lstat on it). */
1544 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1545 VOLUME_NAME_DOS);
1546 if(!buf_size)
1547 return FALSE;
1548
1549 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001550 if (!buf) {
1551 SetLastError(ERROR_OUTOFMEMORY);
1552 return FALSE;
1553 }
1554
Brian Curtind25aef52011-06-13 15:16:04 -05001555 result_length = Py_GetFinalPathNameByHandleW(hdl,
1556 buf, buf_size, VOLUME_NAME_DOS);
1557
1558 if(!result_length) {
1559 free(buf);
1560 return FALSE;
1561 }
1562
1563 if(!CloseHandle(hdl)) {
1564 free(buf);
1565 return FALSE;
1566 }
1567
1568 buf[result_length] = 0;
1569
1570 *target_path = buf;
1571 return TRUE;
1572}
1573
1574static int
1575win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1576 BOOL traverse);
1577static int
1578win32_xstat_impl(const char *path, struct win32_stat *result,
1579 BOOL traverse)
1580{
Victor Stinner26de69d2011-06-17 15:15:38 +02001581 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001582 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001584 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001585 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 const char *dot;
1587
Brian Curtind25aef52011-06-13 15:16:04 -05001588 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001589 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1590 traverse reparse point. */
1591 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001592 }
1593
Brian Curtinf5e76d02010-11-24 13:14:05 +00001594 hFile = CreateFileA(
1595 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001596 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001597 0, /* share mode */
1598 NULL, /* security attributes */
1599 OPEN_EXISTING,
1600 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001601 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1602 Because of this, calls like GetFinalPathNameByHandle will return
1603 the symlink path agin and not the actual final path. */
1604 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1605 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001606 NULL);
1607
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001608 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 /* Either the target doesn't exist, or we don't have access to
1610 get a handle to it. If the former, we need to return an error.
1611 If the latter, we can use attributes_from_dir. */
1612 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 return -1;
1614 /* Could not get attributes on open file. Fall back to
1615 reading the directory. */
1616 if (!attributes_from_dir(path, &info, &reparse_tag))
1617 /* Very strange. This should not fail now */
1618 return -1;
1619 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1620 if (traverse) {
1621 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 } else {
1627 if (!GetFileInformationByHandle(hFile, &info)) {
1628 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001629 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 }
1631 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001632 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1633 return -1;
1634
1635 /* Close the outer open file handle now that we're about to
1636 reopen it with different flags. */
1637 if (!CloseHandle(hFile))
1638 return -1;
1639
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001641 /* In order to call GetFinalPathNameByHandle we need to open
1642 the file without the reparse handling flag set. */
1643 hFile2 = CreateFileA(
1644 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1645 NULL, OPEN_EXISTING,
1646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1647 NULL);
1648 if (hFile2 == INVALID_HANDLE_VALUE)
1649 return -1;
1650
1651 if (!get_target_path(hFile2, &target_path))
1652 return -1;
1653
1654 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001655 free(target_path);
1656 return code;
1657 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001658 } else
1659 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001661 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662
1663 /* Set S_IEXEC if it is an .exe, .bat, ... */
1664 dot = strrchr(path, '.');
1665 if (dot) {
1666 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1667 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1668 result->st_mode |= 0111;
1669 }
1670 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671}
1672
1673static int
Brian Curtind25aef52011-06-13 15:16:04 -05001674win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1675 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676{
1677 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001678 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001679 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001680 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001681 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682 const wchar_t *dot;
1683
Brian Curtind25aef52011-06-13 15:16:04 -05001684 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001685 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1686 traverse reparse point. */
1687 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688 }
1689
Brian Curtinf5e76d02010-11-24 13:14:05 +00001690 hFile = CreateFileW(
1691 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001692 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001693 0, /* share mode */
1694 NULL, /* security attributes */
1695 OPEN_EXISTING,
1696 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001697 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1698 Because of this, calls like GetFinalPathNameByHandle will return
1699 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001700 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001701 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001702 NULL);
1703
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001704 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705 /* Either the target doesn't exist, or we don't have access to
1706 get a handle to it. If the former, we need to return an error.
1707 If the latter, we can use attributes_from_dir. */
1708 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 return -1;
1710 /* Could not get attributes on open file. Fall back to
1711 reading the directory. */
1712 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1713 /* Very strange. This should not fail now */
1714 return -1;
1715 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1716 if (traverse) {
1717 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001718 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001720 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 } else {
1723 if (!GetFileInformationByHandle(hFile, &info)) {
1724 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001725 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 }
1727 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001728 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1729 return -1;
1730
1731 /* Close the outer open file handle now that we're about to
1732 reopen it with different flags. */
1733 if (!CloseHandle(hFile))
1734 return -1;
1735
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001736 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001737 /* In order to call GetFinalPathNameByHandle we need to open
1738 the file without the reparse handling flag set. */
1739 hFile2 = CreateFileW(
1740 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1741 NULL, OPEN_EXISTING,
1742 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1743 NULL);
1744 if (hFile2 == INVALID_HANDLE_VALUE)
1745 return -1;
1746
1747 if (!get_target_path(hFile2, &target_path))
1748 return -1;
1749
1750 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001751 free(target_path);
1752 return code;
1753 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001754 } else
1755 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001757 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001758
1759 /* Set S_IEXEC if it is an .exe, .bat, ... */
1760 dot = wcsrchr(path, '.');
1761 if (dot) {
1762 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1763 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1764 result->st_mode |= 0111;
1765 }
1766 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767}
1768
1769static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001771{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 /* Protocol violation: we explicitly clear errno, instead of
1773 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001774 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001775 errno = 0;
1776 return code;
1777}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001778
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001779static int
1780win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1781{
1782 /* Protocol violation: we explicitly clear errno, instead of
1783 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001784 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 errno = 0;
1786 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001787}
Brian Curtind25aef52011-06-13 15:16:04 -05001788/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001789
1790 In Posix, stat automatically traverses symlinks and returns the stat
1791 structure for the target. In Windows, the equivalent GetFileAttributes by
1792 default does not traverse symlinks and instead returns attributes for
1793 the symlink.
1794
1795 Therefore, win32_lstat will get the attributes traditionally, and
1796 win32_stat will first explicitly resolve the symlink target and then will
1797 call win32_lstat on that result.
1798
Ezio Melotti4969f702011-03-15 05:59:46 +02001799 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001800
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001801static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001802win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001803{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001804 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001805}
1806
Victor Stinner8c62be82010-05-06 00:08:46 +00001807static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001808win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001809{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001810 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001811}
1812
1813static int
1814win32_stat(const char* path, struct win32_stat *result)
1815{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001816 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001817}
1818
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001819static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001820win32_stat_w(const wchar_t* path, struct win32_stat *result)
1821{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001822 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001823}
1824
1825static int
1826win32_fstat(int file_number, struct win32_stat *result)
1827{
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 BY_HANDLE_FILE_INFORMATION info;
1829 HANDLE h;
1830 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001831
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001832 if (!_PyVerify_fd(file_number))
1833 h = INVALID_HANDLE_VALUE;
1834 else
1835 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001836
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 /* Protocol violation: we explicitly clear errno, instead of
1838 setting it to a POSIX error. Callers should use GetLastError. */
1839 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001840
Victor Stinner8c62be82010-05-06 00:08:46 +00001841 if (h == INVALID_HANDLE_VALUE) {
1842 /* This is really a C library error (invalid file handle).
1843 We set the Win32 error to the closes one matching. */
1844 SetLastError(ERROR_INVALID_HANDLE);
1845 return -1;
1846 }
1847 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001848
Victor Stinner8c62be82010-05-06 00:08:46 +00001849 type = GetFileType(h);
1850 if (type == FILE_TYPE_UNKNOWN) {
1851 DWORD error = GetLastError();
1852 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001853 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001854 }
1855 /* else: valid but unknown file */
1856 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001857
Victor Stinner8c62be82010-05-06 00:08:46 +00001858 if (type != FILE_TYPE_DISK) {
1859 if (type == FILE_TYPE_CHAR)
1860 result->st_mode = _S_IFCHR;
1861 else if (type == FILE_TYPE_PIPE)
1862 result->st_mode = _S_IFIFO;
1863 return 0;
1864 }
1865
1866 if (!GetFileInformationByHandle(h, &info)) {
1867 return -1;
1868 }
1869
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001870 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001872 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1873 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001874}
1875
1876#endif /* MS_WINDOWS */
1877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001879"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001880This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001881 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001882or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1883\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001884Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1885or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001886\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001887See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001888
1889static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001890 {"st_mode", "protection bits"},
1891 {"st_ino", "inode"},
1892 {"st_dev", "device"},
1893 {"st_nlink", "number of hard links"},
1894 {"st_uid", "user ID of owner"},
1895 {"st_gid", "group ID of owner"},
1896 {"st_size", "total size, in bytes"},
1897 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1898 {NULL, "integer time of last access"},
1899 {NULL, "integer time of last modification"},
1900 {NULL, "integer time of last change"},
1901 {"st_atime", "time of last access"},
1902 {"st_mtime", "time of last modification"},
1903 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001904 {"st_atime_ns", "time of last access in nanoseconds"},
1905 {"st_mtime_ns", "time of last modification in nanoseconds"},
1906 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001907#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 {"st_blksize", "blocksize for filesystem I/O"},
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_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001913#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001915#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001916#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001917 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001918#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001919#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001921#endif
1922#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001923 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001924#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001926};
1927
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001928#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001929#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001930#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001931#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001932#endif
1933
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001934#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001935#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1936#else
1937#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1938#endif
1939
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001940#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001941#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1942#else
1943#define ST_RDEV_IDX ST_BLOCKS_IDX
1944#endif
1945
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001946#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1947#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1948#else
1949#define ST_FLAGS_IDX ST_RDEV_IDX
1950#endif
1951
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001952#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001953#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001954#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001955#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001956#endif
1957
1958#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1959#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1960#else
1961#define ST_BIRTHTIME_IDX ST_GEN_IDX
1962#endif
1963
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001964static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001965 "stat_result", /* name */
1966 stat_result__doc__, /* doc */
1967 stat_result_fields,
1968 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001969};
1970
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001971PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001972"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1973This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001974 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001975or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001976\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001977See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001978
1979static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 {"f_bsize", },
1981 {"f_frsize", },
1982 {"f_blocks", },
1983 {"f_bfree", },
1984 {"f_bavail", },
1985 {"f_files", },
1986 {"f_ffree", },
1987 {"f_favail", },
1988 {"f_flag", },
1989 {"f_namemax",},
1990 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001991};
1992
1993static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001994 "statvfs_result", /* name */
1995 statvfs_result__doc__, /* doc */
1996 statvfs_result_fields,
1997 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001998};
1999
Ross Lagerwall7807c352011-03-17 20:20:30 +02002000#if defined(HAVE_WAITID) && !defined(__APPLE__)
2001PyDoc_STRVAR(waitid_result__doc__,
2002"waitid_result: Result from waitid.\n\n\
2003This object may be accessed either as a tuple of\n\
2004 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2005or via the attributes si_pid, si_uid, and so on.\n\
2006\n\
2007See os.waitid for more information.");
2008
2009static PyStructSequence_Field waitid_result_fields[] = {
2010 {"si_pid", },
2011 {"si_uid", },
2012 {"si_signo", },
2013 {"si_status", },
2014 {"si_code", },
2015 {0}
2016};
2017
2018static PyStructSequence_Desc waitid_result_desc = {
2019 "waitid_result", /* name */
2020 waitid_result__doc__, /* doc */
2021 waitid_result_fields,
2022 5
2023};
2024static PyTypeObject WaitidResultType;
2025#endif
2026
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002027static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002028static PyTypeObject StatResultType;
2029static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002030#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002031static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002032#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002033static newfunc structseq_new;
2034
2035static PyObject *
2036statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2037{
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 PyStructSequence *result;
2039 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002040
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 result = (PyStructSequence*)structseq_new(type, args, kwds);
2042 if (!result)
2043 return NULL;
2044 /* If we have been initialized from a tuple,
2045 st_?time might be set to None. Initialize it
2046 from the int slots. */
2047 for (i = 7; i <= 9; i++) {
2048 if (result->ob_item[i+3] == Py_None) {
2049 Py_DECREF(Py_None);
2050 Py_INCREF(result->ob_item[i]);
2051 result->ob_item[i+3] = result->ob_item[i];
2052 }
2053 }
2054 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002055}
2056
2057
2058
2059/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002060static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002061
2062PyDoc_STRVAR(stat_float_times__doc__,
2063"stat_float_times([newval]) -> oldval\n\n\
2064Determine whether os.[lf]stat represents time stamps as float objects.\n\
2065If newval is True, future calls to stat() return floats, if it is False,\n\
2066future calls return ints. \n\
2067If newval is omitted, return the current setting.\n");
2068
2069static PyObject*
2070stat_float_times(PyObject* self, PyObject *args)
2071{
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 int newval = -1;
2073 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2074 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002075 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2076 "stat_float_times() is deprecated",
2077 1))
2078 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002079 if (newval == -1)
2080 /* Return old value */
2081 return PyBool_FromLong(_stat_float_times);
2082 _stat_float_times = newval;
2083 Py_INCREF(Py_None);
2084 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002085}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002086
Larry Hastings6fe20b32012-04-19 15:07:49 -07002087static PyObject *billion = NULL;
2088
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002089static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002090fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002091{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002092 PyObject *s = _PyLong_FromTime_t(sec);
2093 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2094 PyObject *s_in_ns = NULL;
2095 PyObject *ns_total = NULL;
2096 PyObject *float_s = NULL;
2097
2098 if (!(s && ns_fractional))
2099 goto exit;
2100
2101 s_in_ns = PyNumber_Multiply(s, billion);
2102 if (!s_in_ns)
2103 goto exit;
2104
2105 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2106 if (!ns_total)
2107 goto exit;
2108
Victor Stinner4195b5c2012-02-08 23:03:19 +01002109 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002110 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2111 if (!float_s)
2112 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002114 else {
2115 float_s = s;
2116 Py_INCREF(float_s);
2117 }
2118
2119 PyStructSequence_SET_ITEM(v, index, s);
2120 PyStructSequence_SET_ITEM(v, index+3, float_s);
2121 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2122 s = NULL;
2123 float_s = NULL;
2124 ns_total = NULL;
2125exit:
2126 Py_XDECREF(s);
2127 Py_XDECREF(ns_fractional);
2128 Py_XDECREF(s_in_ns);
2129 Py_XDECREF(ns_total);
2130 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002131}
2132
Tim Peters5aa91602002-01-30 05:46:57 +00002133/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002134 (used by posix_stat() and posix_fstat()) */
2135static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002136_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002137{
Victor Stinner8c62be82010-05-06 00:08:46 +00002138 unsigned long ansec, mnsec, cnsec;
2139 PyObject *v = PyStructSequence_New(&StatResultType);
2140 if (v == NULL)
2141 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002142
Victor Stinner8c62be82010-05-06 00:08:46 +00002143 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002144#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002145 PyStructSequence_SET_ITEM(v, 1,
2146 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002147#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002148 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002149#endif
2150#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002151 PyStructSequence_SET_ITEM(v, 2,
2152 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002153#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002154 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002155#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002156 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
2157 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
2158 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00002159#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 PyStructSequence_SET_ITEM(v, 6,
2161 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002162#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002163 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002164#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002165
Martin v. Löwis14694662006-02-03 12:54:16 +00002166#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002167 ansec = st->st_atim.tv_nsec;
2168 mnsec = st->st_mtim.tv_nsec;
2169 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002170#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002171 ansec = st->st_atimespec.tv_nsec;
2172 mnsec = st->st_mtimespec.tv_nsec;
2173 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002174#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002175 ansec = st->st_atime_nsec;
2176 mnsec = st->st_mtime_nsec;
2177 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002178#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002179 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002180#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002181 fill_time(v, 7, st->st_atime, ansec);
2182 fill_time(v, 8, st->st_mtime, mnsec);
2183 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002184
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002185#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002186 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2187 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002188#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002189#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002190 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2191 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002192#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002193#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002194 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2195 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002196#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002197#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002198 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2199 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002200#endif
2201#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002203 PyObject *val;
2204 unsigned long bsec,bnsec;
2205 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002206#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002207 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002208#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002209 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002210#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002211 if (_stat_float_times) {
2212 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2213 } else {
2214 val = PyLong_FromLong((long)bsec);
2215 }
2216 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2217 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002218 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002219#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002220#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002221 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2222 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002223#endif
Fred Drake699f3522000-06-29 21:12:41 +00002224
Victor Stinner8c62be82010-05-06 00:08:46 +00002225 if (PyErr_Occurred()) {
2226 Py_DECREF(v);
2227 return NULL;
2228 }
Fred Drake699f3522000-06-29 21:12:41 +00002229
Victor Stinner8c62be82010-05-06 00:08:46 +00002230 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002231}
2232
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002233/* POSIX methods */
2234
Guido van Rossum94f6f721999-01-06 18:42:14 +00002235
2236static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002237posix_do_stat(char *function_name, path_t *path,
2238 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002239{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002240 STRUCT_STAT st;
2241 int result;
2242
2243#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2244 if (follow_symlinks_specified(function_name, follow_symlinks))
2245 return NULL;
2246#endif
2247
2248 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2249 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2250 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2251 return NULL;
2252
2253 Py_BEGIN_ALLOW_THREADS
2254 if (path->fd != -1)
2255 result = FSTAT(path->fd, &st);
2256 else
2257#ifdef MS_WINDOWS
2258 if (path->wide) {
2259 if (follow_symlinks)
2260 result = win32_stat_w(path->wide, &st);
2261 else
2262 result = win32_lstat_w(path->wide, &st);
2263 }
2264 else
2265#endif
2266#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2267 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2268 result = LSTAT(path->narrow, &st);
2269 else
2270#endif
2271#ifdef HAVE_FSTATAT
2272 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2273 result = fstatat(dir_fd, path->narrow, &st,
2274 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2275 else
2276#endif
2277 result = STAT(path->narrow, &st);
2278 Py_END_ALLOW_THREADS
2279
2280 if (result != 0)
2281 return path_error("stat", path);
2282
2283 return _pystat_fromstructstat(&st);
2284}
2285
2286PyDoc_STRVAR(posix_stat__doc__,
2287"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2288Perform a stat system call on the given path.\n\
2289\n\
2290path may be specified as either a string or as an open file descriptor.\n\
2291\n\
2292If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2293 and path should be relative; path will then be relative to that directory.\n\
2294 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2295 it will raise a NotImplementedError.\n\
2296If follow_symlinks is False, and the last element of the path is a symbolic\n\
2297 link, stat will examine the symbolic link itself instead of the file the\n\
2298 link points to.\n\
2299It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2300 an open file descriptor.");
2301
2302static PyObject *
2303posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2304{
2305 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2306 path_t path;
2307 int dir_fd = DEFAULT_DIR_FD;
2308 int follow_symlinks = 1;
2309 PyObject *return_value;
2310
2311 memset(&path, 0, sizeof(path));
2312 path.allow_fd = 1;
2313 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2314 path_converter, &path,
2315#ifdef HAVE_FSTATAT
2316 dir_fd_converter, &dir_fd,
2317#else
2318 dir_fd_unavailable, &dir_fd,
2319#endif
2320 &follow_symlinks))
2321 return NULL;
2322 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2323 path_cleanup(&path);
2324 return return_value;
2325}
2326
2327PyDoc_STRVAR(posix_lstat__doc__,
2328"lstat(path, *, dir_fd=None) -> stat result\n\n\
2329Like stat(), but do not follow symbolic links.\n\
2330Equivalent to stat(path, follow_symlinks=False).");
2331
2332static PyObject *
2333posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2334{
2335 static char *keywords[] = {"path", "dir_fd", NULL};
2336 path_t path;
2337 int dir_fd = DEFAULT_DIR_FD;
2338 int follow_symlinks = 0;
2339 PyObject *return_value;
2340
2341 memset(&path, 0, sizeof(path));
2342 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2343 path_converter, &path,
2344#ifdef HAVE_FSTATAT
2345 dir_fd_converter, &dir_fd
2346#else
2347 dir_fd_unavailable, &dir_fd
2348#endif
2349 ))
2350 return NULL;
2351 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2352 path_cleanup(&path);
2353 return return_value;
2354}
2355
2356PyDoc_STRVAR(posix_access__doc__,
2357"access(path, mode, *, dir_fd=None, effective_ids=False,\
2358 follow_symlinks=True)\n\n\
2359Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2360False otherwise.\n\
2361\n\
2362If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2363 and path should be relative; path will then be relative to that directory.\n\
2364If effective_ids is True, access will use the effective uid/gid instead of\n\
2365 the real uid/gid.\n\
2366If follow_symlinks is False, and the last element of the path is a symbolic\n\
2367 link, access will examine the symbolic link itself instead of the file the\n\
2368 link points to.\n\
2369dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2370 on your platform. If they are unavailable, using them will raise a\n\
2371 NotImplementedError.\n\
2372\n\
2373Note that most operations will use the effective uid/gid, therefore this\n\
2374 routine can be used in a suid/sgid environment to test if the invoking user\n\
2375 has the specified access to the path.\n\
2376The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2377 of R_OK, W_OK, and X_OK.");
2378
2379static PyObject *
2380posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2381{
2382 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2383 "follow_symlinks", NULL};
2384 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002385 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002386 int dir_fd = DEFAULT_DIR_FD;
2387 int effective_ids = 0;
2388 int follow_symlinks = 1;
2389 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002390
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002391#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002392 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002393#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002394 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002395#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002396
2397 memset(&path, 0, sizeof(path));
2398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2399 path_converter, &path, &mode,
2400#ifdef HAVE_FACCESSAT
2401 dir_fd_converter, &dir_fd,
2402#else
2403 dir_fd_unavailable, &dir_fd,
2404#endif
2405 &effective_ids, &follow_symlinks))
2406 return NULL;
2407
2408#ifndef HAVE_FACCESSAT
2409 if (follow_symlinks_specified("access", follow_symlinks))
2410 goto exit;
2411
2412 if (effective_ids) {
2413 argument_unavailable_error("access", "effective_ids");
2414 goto exit;
2415 }
2416#endif
2417
2418#ifdef MS_WINDOWS
2419 Py_BEGIN_ALLOW_THREADS
2420 if (path.wide != NULL)
2421 attr = GetFileAttributesW(path.wide);
2422 else
2423 attr = GetFileAttributesA(path.narrow);
2424 Py_END_ALLOW_THREADS
2425
2426 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002427 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002428 * * we didn't get a -1, and
2429 * * write access wasn't requested,
2430 * * or the file isn't read-only,
2431 * * or it's a directory.
2432 * (Directories cannot be read-only on Windows.)
2433 */
2434 return_value = PyBool_FromLong(
2435 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002436 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002437 !(attr & FILE_ATTRIBUTE_READONLY) ||
2438 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2439#else
2440
2441 Py_BEGIN_ALLOW_THREADS
2442#ifdef HAVE_FACCESSAT
2443 if ((dir_fd != DEFAULT_DIR_FD) ||
2444 effective_ids ||
2445 !follow_symlinks) {
2446 int flags = 0;
2447 if (!follow_symlinks)
2448 flags |= AT_SYMLINK_NOFOLLOW;
2449 if (effective_ids)
2450 flags |= AT_EACCESS;
2451 result = faccessat(dir_fd, path.narrow, mode, flags);
2452 }
2453 else
2454#endif
2455 result = access(path.narrow, mode);
2456 Py_END_ALLOW_THREADS
2457 return_value = PyBool_FromLong(!result);
2458#endif
2459
2460#ifndef HAVE_FACCESSAT
2461exit:
2462#endif
2463 path_cleanup(&path);
2464 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002465}
2466
Guido van Rossumd371ff11999-01-25 16:12:23 +00002467#ifndef F_OK
2468#define F_OK 0
2469#endif
2470#ifndef R_OK
2471#define R_OK 4
2472#endif
2473#ifndef W_OK
2474#define W_OK 2
2475#endif
2476#ifndef X_OK
2477#define X_OK 1
2478#endif
2479
2480#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002481PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002482"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002483Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002484
2485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002486posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002487{
Victor Stinner8c62be82010-05-06 00:08:46 +00002488 int id;
2489 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002490
Victor Stinner8c62be82010-05-06 00:08:46 +00002491 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2492 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002493
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002494#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002495 /* file descriptor 0 only, the default input device (stdin) */
2496 if (id == 0) {
2497 ret = ttyname();
2498 }
2499 else {
2500 ret = NULL;
2501 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002502#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002503 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002504#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002505 if (ret == NULL)
2506 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002507 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002508}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002509#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002510
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002511#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002512PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002513"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002514Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002515
2516static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002517posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002518{
Victor Stinner8c62be82010-05-06 00:08:46 +00002519 char *ret;
2520 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002521
Greg Wardb48bc172000-03-01 21:51:56 +00002522#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002523 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002524#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002525 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002526#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002527 if (ret == NULL)
2528 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002529 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002530}
2531#endif
2532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002533PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002534"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002535Change the current working directory to the specified path.\n\
2536\n\
2537path may always be specified as a string.\n\
2538On some platforms, path may also be specified as an open file descriptor.\n\
2539 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002540
Barry Warsaw53699e91996-12-10 23:23:01 +00002541static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002542posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002543{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002544 path_t path;
2545 int result;
2546 PyObject *return_value = NULL;
2547 static char *keywords[] = {"path", NULL};
2548
2549 memset(&path, 0, sizeof(path));
2550#ifdef HAVE_FCHDIR
2551 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002552#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002553 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2554 path_converter, &path
2555 ))
2556 return NULL;
2557
2558 Py_BEGIN_ALLOW_THREADS
2559#ifdef MS_WINDOWS
2560 if (path.wide)
2561 result = win32_wchdir(path.wide);
2562 else
2563 result = win32_chdir(path.narrow);
2564 result = !result; /* on unix, success = 0, on windows, success = !0 */
2565#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2566 result = _chdir2(path.narrow);
2567#else
2568#ifdef HAVE_FCHDIR
2569 if (path.fd != -1)
2570 result = fchdir(path.fd);
2571 else
2572#endif
2573 result = chdir(path.narrow);
2574#endif
2575 Py_END_ALLOW_THREADS
2576
2577 if (result) {
2578 return_value = path_error("chdir", &path);
2579 goto exit;
2580 }
2581
2582 return_value = Py_None;
2583 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002584
Larry Hastings9cf065c2012-06-22 16:30:09 -07002585exit:
2586 path_cleanup(&path);
2587 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002588}
2589
Fred Drake4d1e64b2002-04-15 19:40:07 +00002590#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002591PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002592"fchdir(fd)\n\n\
2593Change to the directory of the given file descriptor. fd must be\n\
2594opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002595
2596static PyObject *
2597posix_fchdir(PyObject *self, PyObject *fdobj)
2598{
Victor Stinner8c62be82010-05-06 00:08:46 +00002599 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002600}
2601#endif /* HAVE_FCHDIR */
2602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002604PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2606Change the access permissions of a file.\n\
2607\n\
2608path may always be specified as a string.\n\
2609On some platforms, path may also be specified as an open file descriptor.\n\
2610 If this functionality is unavailable, using it raises an exception.\n\
2611If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2612 and path should be relative; path will then be relative to that directory.\n\
2613If follow_symlinks is False, and the last element of the path is a symbolic\n\
2614 link, chmod will modify the symbolic link itself instead of the file the\n\
2615 link points to.\n\
2616It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2617 an open file descriptor.\n\
2618dir_fd and follow_symlinks may not be implemented on your platform.\n\
2619 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002620
Barry Warsaw53699e91996-12-10 23:23:01 +00002621static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002622posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002623{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624 path_t path;
2625 int mode;
2626 int dir_fd = DEFAULT_DIR_FD;
2627 int follow_symlinks = 1;
2628 int result;
2629 PyObject *return_value = NULL;
2630 static char *keywords[] = {"path", "mode", "dir_fd",
2631 "follow_symlinks", NULL};
2632
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002633#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002634 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002635#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002636
Larry Hastings9cf065c2012-06-22 16:30:09 -07002637#ifdef HAVE_FCHMODAT
2638 int fchmodat_nofollow_unsupported = 0;
2639#endif
2640
2641 memset(&path, 0, sizeof(path));
2642#ifdef HAVE_FCHMOD
2643 path.allow_fd = 1;
2644#endif
2645 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2646 path_converter, &path,
2647 &mode,
2648#ifdef HAVE_FCHMODAT
2649 dir_fd_converter, &dir_fd,
2650#else
2651 dir_fd_unavailable, &dir_fd,
2652#endif
2653 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002654 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002655
2656#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2657 if (follow_symlinks_specified("chmod", follow_symlinks))
2658 goto exit;
2659#endif
2660
2661#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002662 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002663 if (path.wide)
2664 attr = GetFileAttributesW(path.wide);
2665 else
2666 attr = GetFileAttributesA(path.narrow);
2667 if (attr == 0xFFFFFFFF)
2668 result = 0;
2669 else {
2670 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002671 attr &= ~FILE_ATTRIBUTE_READONLY;
2672 else
2673 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002674 if (path.wide)
2675 result = SetFileAttributesW(path.wide, attr);
2676 else
2677 result = SetFileAttributesA(path.narrow, attr);
2678 }
2679 Py_END_ALLOW_THREADS
2680
2681 if (!result) {
2682 return_value = win32_error_object("chmod", path.object);
2683 goto exit;
2684 }
2685#else /* MS_WINDOWS */
2686 Py_BEGIN_ALLOW_THREADS
2687#ifdef HAVE_FCHMOD
2688 if (path.fd != -1)
2689 result = fchmod(path.fd, mode);
2690 else
2691#endif
2692#ifdef HAVE_LCHMOD
2693 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2694 result = lchmod(path.narrow, mode);
2695 else
2696#endif
2697#ifdef HAVE_FCHMODAT
2698 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2699 /*
2700 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2701 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002702 * and then says it isn't implemented yet.
2703 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704 *
2705 * Once it is supported, os.chmod will automatically
2706 * support dir_fd and follow_symlinks=False. (Hopefully.)
2707 * Until then, we need to be careful what exception we raise.
2708 */
2709 result = fchmodat(dir_fd, path.narrow, mode,
2710 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2711 /*
2712 * But wait! We can't throw the exception without allowing threads,
2713 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2714 */
2715 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002716 result &&
2717 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2718 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002719 }
2720 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002721#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002722 result = chmod(path.narrow, mode);
2723 Py_END_ALLOW_THREADS
2724
2725 if (result) {
2726#ifdef HAVE_FCHMODAT
2727 if (fchmodat_nofollow_unsupported) {
2728 if (dir_fd != DEFAULT_DIR_FD)
2729 dir_fd_and_follow_symlinks_invalid("chmod",
2730 dir_fd, follow_symlinks);
2731 else
2732 follow_symlinks_specified("chmod", follow_symlinks);
2733 }
2734 else
2735#endif
2736 return_value = path_error("chmod", &path);
2737 goto exit;
2738 }
2739#endif
2740
2741 Py_INCREF(Py_None);
2742 return_value = Py_None;
2743exit:
2744 path_cleanup(&path);
2745 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002746}
2747
Larry Hastings9cf065c2012-06-22 16:30:09 -07002748
Christian Heimes4e30a842007-11-30 22:12:06 +00002749#ifdef HAVE_FCHMOD
2750PyDoc_STRVAR(posix_fchmod__doc__,
2751"fchmod(fd, mode)\n\n\
2752Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002753descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002754
2755static PyObject *
2756posix_fchmod(PyObject *self, PyObject *args)
2757{
Victor Stinner8c62be82010-05-06 00:08:46 +00002758 int fd, mode, res;
2759 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2760 return NULL;
2761 Py_BEGIN_ALLOW_THREADS
2762 res = fchmod(fd, mode);
2763 Py_END_ALLOW_THREADS
2764 if (res < 0)
2765 return posix_error();
2766 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002767}
2768#endif /* HAVE_FCHMOD */
2769
2770#ifdef HAVE_LCHMOD
2771PyDoc_STRVAR(posix_lchmod__doc__,
2772"lchmod(path, mode)\n\n\
2773Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002774affects the link itself rather than the target.\n\
2775Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002776
2777static PyObject *
2778posix_lchmod(PyObject *self, PyObject *args)
2779{
Victor Stinner8c62be82010-05-06 00:08:46 +00002780 PyObject *opath;
2781 char *path;
2782 int i;
2783 int res;
2784 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2785 &opath, &i))
2786 return NULL;
2787 path = PyBytes_AsString(opath);
2788 Py_BEGIN_ALLOW_THREADS
2789 res = lchmod(path, i);
2790 Py_END_ALLOW_THREADS
2791 if (res < 0)
2792 return posix_error_with_allocated_filename(opath);
2793 Py_DECREF(opath);
2794 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002795}
2796#endif /* HAVE_LCHMOD */
2797
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002798
Thomas Wouterscf297e42007-02-23 15:07:44 +00002799#ifdef HAVE_CHFLAGS
2800PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801"chflags(path, flags, *, follow_symlinks=True)\n\n\
2802Set file flags.\n\
2803\n\
2804If follow_symlinks is False, and the last element of the path is a symbolic\n\
2805 link, chflags will change flags on the symbolic link itself instead of the\n\
2806 file the link points to.\n\
2807follow_symlinks may not be implemented on your platform. If it is\n\
2808unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002809
2810static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002812{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002814 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002815 int follow_symlinks = 1;
2816 int result;
2817 PyObject *return_value;
2818 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2819
2820 memset(&path, 0, sizeof(path));
2821 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2822 path_converter, &path,
2823 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002824 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825
2826#ifndef HAVE_LCHFLAGS
2827 if (follow_symlinks_specified("chflags", follow_symlinks))
2828 goto exit;
2829#endif
2830
Victor Stinner8c62be82010-05-06 00:08:46 +00002831 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002832#ifdef HAVE_LCHFLAGS
2833 if (!follow_symlinks)
2834 result = lchflags(path.narrow, flags);
2835 else
2836#endif
2837 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839
2840 if (result) {
2841 return_value = path_posix_error("chflags", &path);
2842 goto exit;
2843 }
2844
2845 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002847
2848exit:
2849 path_cleanup(&path);
2850 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002851}
2852#endif /* HAVE_CHFLAGS */
2853
2854#ifdef HAVE_LCHFLAGS
2855PyDoc_STRVAR(posix_lchflags__doc__,
2856"lchflags(path, flags)\n\n\
2857Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002858This function will not follow symbolic links.\n\
2859Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002860
2861static PyObject *
2862posix_lchflags(PyObject *self, PyObject *args)
2863{
Victor Stinner8c62be82010-05-06 00:08:46 +00002864 PyObject *opath;
2865 char *path;
2866 unsigned long flags;
2867 int res;
2868 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2869 PyUnicode_FSConverter, &opath, &flags))
2870 return NULL;
2871 path = PyBytes_AsString(opath);
2872 Py_BEGIN_ALLOW_THREADS
2873 res = lchflags(path, flags);
2874 Py_END_ALLOW_THREADS
2875 if (res < 0)
2876 return posix_error_with_allocated_filename(opath);
2877 Py_DECREF(opath);
2878 Py_INCREF(Py_None);
2879 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002880}
2881#endif /* HAVE_LCHFLAGS */
2882
Martin v. Löwis244edc82001-10-04 22:44:26 +00002883#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002884PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002885"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002887
2888static PyObject *
2889posix_chroot(PyObject *self, PyObject *args)
2890{
Victor Stinner8c62be82010-05-06 00:08:46 +00002891 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002892}
2893#endif
2894
Guido van Rossum21142a01999-01-08 21:05:37 +00002895#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002897"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002898force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002899
2900static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002901posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002902{
Stefan Krah0e803b32010-11-26 16:16:47 +00002903 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002904}
2905#endif /* HAVE_FSYNC */
2906
Ross Lagerwall7807c352011-03-17 20:20:30 +02002907#ifdef HAVE_SYNC
2908PyDoc_STRVAR(posix_sync__doc__,
2909"sync()\n\n\
2910Force write of everything to disk.");
2911
2912static PyObject *
2913posix_sync(PyObject *self, PyObject *noargs)
2914{
2915 Py_BEGIN_ALLOW_THREADS
2916 sync();
2917 Py_END_ALLOW_THREADS
2918 Py_RETURN_NONE;
2919}
2920#endif
2921
Guido van Rossum21142a01999-01-08 21:05:37 +00002922#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002923
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002924#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002925extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2926#endif
2927
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002928PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002929"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002930force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002931 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002932
2933static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002934posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002935{
Stefan Krah0e803b32010-11-26 16:16:47 +00002936 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002937}
2938#endif /* HAVE_FDATASYNC */
2939
2940
Fredrik Lundh10723342000-07-10 16:38:09 +00002941#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002942PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002943"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
2944Change the owner and group id of path to the numeric uid and gid.\n\
2945\n\
2946path may always be specified as a string.\n\
2947On some platforms, path may also be specified as an open file descriptor.\n\
2948 If this functionality is unavailable, using it raises an exception.\n\
2949If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2950 and path should be relative; path will then be relative to that directory.\n\
2951If follow_symlinks is False, and the last element of the path is a symbolic\n\
2952 link, chown will modify the symbolic link itself instead of the file the\n\
2953 link points to.\n\
2954It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2955 an open file descriptor.\n\
2956dir_fd and follow_symlinks may not be implemented on your platform.\n\
2957 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002958
Barry Warsaw53699e91996-12-10 23:23:01 +00002959static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002960posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002961{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 path_t path;
2963 long uid_l, gid_l;
2964 uid_t uid;
2965 gid_t gid;
2966 int dir_fd = DEFAULT_DIR_FD;
2967 int follow_symlinks = 1;
2968 int result;
2969 PyObject *return_value = NULL;
2970 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
2971 "follow_symlinks", NULL};
2972
2973 memset(&path, 0, sizeof(path));
2974#ifdef HAVE_FCHOWN
2975 path.allow_fd = 1;
2976#endif
2977 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
2978 path_converter, &path,
2979 &uid_l, &gid_l,
2980#ifdef HAVE_FCHOWNAT
2981 dir_fd_converter, &dir_fd,
2982#else
2983 dir_fd_unavailable, &dir_fd,
2984#endif
2985 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002986 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987
2988#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
2989 if (follow_symlinks_specified("chown", follow_symlinks))
2990 goto exit;
2991#endif
2992 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
2993 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
2994 goto exit;
2995
2996#ifdef __APPLE__
2997 /*
2998 * This is for Mac OS X 10.3, which doesn't have lchown.
2999 * (But we still have an lchown symbol because of weak-linking.)
3000 * It doesn't have fchownat either. So there's no possibility
3001 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003002 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003003 if ((!follow_symlinks) && (lchown == NULL)) {
3004 follow_symlinks_specified("chown", follow_symlinks);
3005 goto exit;
3006 }
3007#endif
3008
Victor Stinner8c62be82010-05-06 00:08:46 +00003009 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003010 uid = (uid_t)uid_l;
3011 gid = (uid_t)gid_l;
3012#ifdef HAVE_FCHOWN
3013 if (path.fd != -1)
3014 result = fchown(path.fd, uid, gid);
3015 else
3016#endif
3017#ifdef HAVE_LCHOWN
3018 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3019 result = lchown(path.narrow, uid, gid);
3020 else
3021#endif
3022#ifdef HAVE_FCHOWNAT
3023 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3024 result = fchownat(dir_fd, path.narrow, uid, gid,
3025 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3026 else
3027#endif
3028 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003029 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003030
3031 if (result) {
3032 return_value = path_posix_error("chown", &path);
3033 goto exit;
3034 }
3035
3036 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003037 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003038
3039exit:
3040 path_cleanup(&path);
3041 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003042}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003043#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003044
Christian Heimes4e30a842007-11-30 22:12:06 +00003045#ifdef HAVE_FCHOWN
3046PyDoc_STRVAR(posix_fchown__doc__,
3047"fchown(fd, uid, gid)\n\n\
3048Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003049fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003050
3051static PyObject *
3052posix_fchown(PyObject *self, PyObject *args)
3053{
Victor Stinner8c62be82010-05-06 00:08:46 +00003054 int fd;
3055 long uid, gid;
3056 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02003057 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003058 return NULL;
3059 Py_BEGIN_ALLOW_THREADS
3060 res = fchown(fd, (uid_t) uid, (gid_t) gid);
3061 Py_END_ALLOW_THREADS
3062 if (res < 0)
3063 return posix_error();
3064 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003065}
3066#endif /* HAVE_FCHOWN */
3067
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003068#ifdef HAVE_LCHOWN
3069PyDoc_STRVAR(posix_lchown__doc__,
3070"lchown(path, uid, gid)\n\n\
3071Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072This function will not follow symbolic links.\n\
3073Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003074
3075static PyObject *
3076posix_lchown(PyObject *self, PyObject *args)
3077{
Victor Stinner8c62be82010-05-06 00:08:46 +00003078 PyObject *opath;
3079 char *path;
3080 long uid, gid;
3081 int res;
3082 if (!PyArg_ParseTuple(args, "O&ll:lchown",
3083 PyUnicode_FSConverter, &opath,
3084 &uid, &gid))
3085 return NULL;
3086 path = PyBytes_AsString(opath);
3087 Py_BEGIN_ALLOW_THREADS
3088 res = lchown(path, (uid_t) uid, (gid_t) gid);
3089 Py_END_ALLOW_THREADS
3090 if (res < 0)
3091 return posix_error_with_allocated_filename(opath);
3092 Py_DECREF(opath);
3093 Py_INCREF(Py_None);
3094 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003095}
3096#endif /* HAVE_LCHOWN */
3097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003098
Guido van Rossum36bc6801995-06-14 22:54:23 +00003099#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003100static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003101posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003102{
Victor Stinner8c62be82010-05-06 00:08:46 +00003103 char buf[1026];
3104 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003105
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003106#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003107 if (!use_bytes) {
3108 wchar_t wbuf[1026];
3109 wchar_t *wbuf2 = wbuf;
3110 PyObject *resobj;
3111 DWORD len;
3112 Py_BEGIN_ALLOW_THREADS
3113 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3114 /* If the buffer is large enough, len does not include the
3115 terminating \0. If the buffer is too small, len includes
3116 the space needed for the terminator. */
3117 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3118 wbuf2 = malloc(len * sizeof(wchar_t));
3119 if (wbuf2)
3120 len = GetCurrentDirectoryW(len, wbuf2);
3121 }
3122 Py_END_ALLOW_THREADS
3123 if (!wbuf2) {
3124 PyErr_NoMemory();
3125 return NULL;
3126 }
3127 if (!len) {
3128 if (wbuf2 != wbuf) free(wbuf2);
3129 return win32_error("getcwdu", NULL);
3130 }
3131 resobj = PyUnicode_FromWideChar(wbuf2, len);
3132 if (wbuf2 != wbuf) free(wbuf2);
3133 return resobj;
3134 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003135
3136 if (win32_warn_bytes_api())
3137 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003138#endif
3139
Victor Stinner8c62be82010-05-06 00:08:46 +00003140 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003141#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003142 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003143#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003144 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003145#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003146 Py_END_ALLOW_THREADS
3147 if (res == NULL)
3148 return posix_error();
3149 if (use_bytes)
3150 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003151 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003152}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003153
3154PyDoc_STRVAR(posix_getcwd__doc__,
3155"getcwd() -> path\n\n\
3156Return a unicode string representing the current working directory.");
3157
3158static PyObject *
3159posix_getcwd_unicode(PyObject *self)
3160{
3161 return posix_getcwd(0);
3162}
3163
3164PyDoc_STRVAR(posix_getcwdb__doc__,
3165"getcwdb() -> path\n\n\
3166Return a bytes string representing the current working directory.");
3167
3168static PyObject *
3169posix_getcwd_bytes(PyObject *self)
3170{
3171 return posix_getcwd(1);
3172}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003173#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003174
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3176#define HAVE_LINK 1
3177#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003178
Guido van Rossumb6775db1994-08-01 11:34:53 +00003179#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003180PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003181"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3182Create a hard link to a file.\n\
3183\n\
3184If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3185 descriptor open to a directory, and the respective path string (src or dst)\n\
3186 should be relative; the path will then be relative to that directory.\n\
3187If follow_symlinks is False, and the last element of src is a symbolic\n\
3188 link, link will create a link to the symbolic link itself instead of the\n\
3189 file the link points to.\n\
3190src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3191 platform. If they are unavailable, using them will raise a\n\
3192 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003193
Barry Warsaw53699e91996-12-10 23:23:01 +00003194static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003195posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003196{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197 path_t src, dst;
3198 int src_dir_fd = DEFAULT_DIR_FD;
3199 int dst_dir_fd = DEFAULT_DIR_FD;
3200 int follow_symlinks = 1;
3201 PyObject *return_value = NULL;
3202 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3203 "follow_symlinks", NULL};
3204#ifdef MS_WINDOWS
3205 BOOL result;
3206#else
3207 int result;
3208#endif
3209
3210 memset(&src, 0, sizeof(src));
3211 memset(&dst, 0, sizeof(dst));
3212 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3213 path_converter, &src,
3214 path_converter, &dst,
3215 dir_fd_converter, &src_dir_fd,
3216 dir_fd_converter, &dst_dir_fd,
3217 &follow_symlinks))
3218 return NULL;
3219
3220#ifndef HAVE_LINKAT
3221 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3222 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3223 goto exit;
3224 }
3225#endif
3226
3227 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3228 PyErr_SetString(PyExc_NotImplementedError,
3229 "link: src and dst must be the same type");
3230 goto exit;
3231 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003232
Brian Curtin1b9df392010-11-24 20:24:31 +00003233#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003234 Py_BEGIN_ALLOW_THREADS
3235 if (src.wide)
3236 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3237 else
3238 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3239 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003240
Larry Hastings9cf065c2012-06-22 16:30:09 -07003241 if (!result) {
3242 return_value = win32_error_object("link", dst.object);
3243 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003244 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003245#else
3246 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003247#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003248 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3249 (dst_dir_fd != DEFAULT_DIR_FD) ||
3250 (!follow_symlinks))
3251 result = linkat(src_dir_fd, src.narrow,
3252 dst_dir_fd, dst.narrow,
3253 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3254 else
3255#endif
3256 result = link(src.narrow, dst.narrow);
3257 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003258
Larry Hastings9cf065c2012-06-22 16:30:09 -07003259 if (result) {
3260 return_value = path_error("link", &dst);
3261 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003262 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003263#endif
3264
3265 return_value = Py_None;
3266 Py_INCREF(Py_None);
3267
3268exit:
3269 path_cleanup(&src);
3270 path_cleanup(&dst);
3271 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003272}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003273#endif
3274
Brian Curtin1b9df392010-11-24 20:24:31 +00003275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003277PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003278"listdir(path='.') -> list_of_filenames\n\n\
3279Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003280The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003281entries '.' and '..' even if they are present in the directory.\n\
3282\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003283path can be specified as either str or bytes. If path is bytes,\n\
3284 the filenames returned will also be bytes; in all other circumstances\n\
3285 the filenames returned will be str.\n\
3286On some platforms, path may also be specified as an open file descriptor;\n\
3287 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003288 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003289
Barry Warsaw53699e91996-12-10 23:23:01 +00003290static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003291posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003292{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003293 path_t path;
3294 PyObject *list = NULL;
3295 static char *keywords[] = {"path", NULL};
3296 int fd = -1;
3297
3298#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3299 PyObject *v;
3300 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3301 BOOL result;
3302 WIN32_FIND_DATA FileData;
3303 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3304 char *bufptr = namebuf;
3305 /* only claim to have space for MAX_PATH */
3306 Py_ssize_t len = sizeof(namebuf)-5;
3307 PyObject *po = NULL;
3308 wchar_t *wnamebuf = NULL;
3309#elif defined(PYOS_OS2)
3310#ifndef MAX_PATH
3311#define MAX_PATH CCHMAXPATH
3312#endif
3313 char *pt;
3314 PyObject *v;
3315 char namebuf[MAX_PATH+5];
3316 HDIR hdir = 1;
3317 ULONG srchcnt = 1;
3318 FILEFINDBUF3 ep;
3319 APIRET rc;
3320#else
3321 PyObject *v;
3322 DIR *dirp = NULL;
3323 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003324 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003325#endif
3326
3327 memset(&path, 0, sizeof(path));
3328 path.nullable = 1;
3329#ifdef HAVE_FDOPENDIR
3330 path.allow_fd = 1;
3331 path.fd = -1;
3332#endif
3333 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3334 path_converter, &path
3335 ))
3336 return NULL;
3337
Victor Stinner8c62be82010-05-06 00:08:46 +00003338 /* XXX Should redo this putting the (now four) versions of opendir
3339 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003340#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003341 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003342 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003343 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003344
Larry Hastings9cf065c2012-06-22 16:30:09 -07003345 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003346 po_wchars = L".";
3347 len = 1;
3348 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003349 po_wchars = path.wide;
3350 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003351 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003353 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3354 if (!wnamebuf) {
3355 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003357 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003358 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003359 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003360 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003361 if (wch != L'/' && wch != L'\\' && wch != L':')
3362 wnamebuf[len++] = L'\\';
3363 wcscpy(wnamebuf + len, L"*.*");
3364 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003365 if ((list = PyList_New(0)) == NULL) {
3366 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003368 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003369 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003370 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003371 if (hFindFile == INVALID_HANDLE_VALUE) {
3372 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373 if (error == ERROR_FILE_NOT_FOUND)
3374 goto exit;
3375 Py_DECREF(list);
3376 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003377 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003378 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 }
3380 do {
3381 /* Skip over . and .. */
3382 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3383 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003384 v = PyUnicode_FromWideChar(wFileData.cFileName,
3385 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003386 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003387 Py_DECREF(list);
3388 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003389 break;
3390 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003392 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003393 Py_DECREF(list);
3394 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003395 break;
3396 }
3397 Py_DECREF(v);
3398 }
3399 Py_BEGIN_ALLOW_THREADS
3400 result = FindNextFileW(hFindFile, &wFileData);
3401 Py_END_ALLOW_THREADS
3402 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3403 it got to the end of the directory. */
3404 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003405 Py_DECREF(list);
3406 list = win32_error_unicode("FindNextFileW", wnamebuf);
3407 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 }
3409 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003410
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413 strcpy(namebuf, path.narrow);
3414 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 if (len > 0) {
3416 char ch = namebuf[len-1];
3417 if (ch != SEP && ch != ALTSEP && ch != ':')
3418 namebuf[len++] = '/';
3419 strcpy(namebuf + len, "*.*");
3420 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003421
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003423 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003424
Antoine Pitroub73caab2010-08-09 23:39:31 +00003425 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003427 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 if (hFindFile == INVALID_HANDLE_VALUE) {
3429 int error = GetLastError();
3430 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431 goto exit;
3432 Py_DECREF(list);
3433 list = win32_error("FindFirstFile", namebuf);
3434 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 }
3436 do {
3437 /* Skip over . and .. */
3438 if (strcmp(FileData.cFileName, ".") != 0 &&
3439 strcmp(FileData.cFileName, "..") != 0) {
3440 v = PyBytes_FromString(FileData.cFileName);
3441 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442 Py_DECREF(list);
3443 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003444 break;
3445 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 Py_DECREF(list);
3449 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003450 break;
3451 }
3452 Py_DECREF(v);
3453 }
3454 Py_BEGIN_ALLOW_THREADS
3455 result = FindNextFile(hFindFile, &FileData);
3456 Py_END_ALLOW_THREADS
3457 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3458 it got to the end of the directory. */
3459 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460 Py_DECREF(list);
3461 list = win32_error("FindNextFile", namebuf);
3462 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003463 }
3464 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003465
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466exit:
3467 if (hFindFile != INVALID_HANDLE_VALUE) {
3468 if (FindClose(hFindFile) == FALSE) {
3469 if (list != NULL) {
3470 Py_DECREF(list);
3471 list = win32_error_object("FindClose", path.object);
3472 }
3473 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003474 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 if (wnamebuf)
3476 free(wnamebuf);
3477 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003478
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003480
Tim Peters0bb44a42000-09-15 07:44:49 +00003481#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003483 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003485 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003486 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003487 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003488 if (*pt == ALTSEP)
3489 *pt = SEP;
3490 if (namebuf[len-1] != SEP)
3491 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003492 strcpy(namebuf + len, "*.*");
3493
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 if ((list = PyList_New(0)) == NULL) {
3495 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003496 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003497
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003498 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3499 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003500 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003501 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3502 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3503 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003504
3505 if (rc != NO_ERROR) {
3506 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 Py_DECREF(list);
3508 list = posix_error_with_filename(path.narrow);
3509 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003510 }
3511
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003512 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003513 do {
3514 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003515 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003516 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003517
3518 strcpy(namebuf, ep.achName);
3519
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003520 /* Leave Case of Name Alone -- In Native Form */
3521 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003522
Christian Heimes72b710a2008-05-26 13:28:38 +00003523 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003524 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 Py_DECREF(list);
3526 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003527 break;
3528 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003530 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 Py_DECREF(list);
3532 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003533 break;
3534 }
3535 Py_DECREF(v);
3536 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3537 }
3538
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539exit:
3540 path_cleanup(&path);
3541
3542 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003543#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003544
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003546#ifdef HAVE_FDOPENDIR
3547 if (path.fd != -1) {
3548 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003549 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003551 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552
3553 if (fd == -1) {
3554 list = posix_error();
3555 goto exit;
3556 }
3557
Larry Hastingsfdaea062012-06-25 04:42:23 -07003558 return_str = 1;
3559
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560 Py_BEGIN_ALLOW_THREADS
3561 dirp = fdopendir(fd);
3562 Py_END_ALLOW_THREADS
3563 }
3564 else
3565#endif
3566 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003567 char *name;
3568 if (path.narrow) {
3569 name = path.narrow;
3570 /* only return bytes if they specified a bytes object */
3571 return_str = !(PyBytes_Check(path.object));
3572 }
3573 else {
3574 name = ".";
3575 return_str = 1;
3576 }
3577
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 Py_BEGIN_ALLOW_THREADS
3579 dirp = opendir(name);
3580 Py_END_ALLOW_THREADS
3581 }
3582
3583 if (dirp == NULL) {
3584 list = path_error("listdir", &path);
3585 goto exit;
3586 }
3587 if ((list = PyList_New(0)) == NULL) {
3588 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 }
3590 for (;;) {
3591 errno = 0;
3592 Py_BEGIN_ALLOW_THREADS
3593 ep = readdir(dirp);
3594 Py_END_ALLOW_THREADS
3595 if (ep == NULL) {
3596 if (errno == 0) {
3597 break;
3598 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 Py_DECREF(list);
3600 list = path_error("listdir", &path);
3601 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 }
3603 }
3604 if (ep->d_name[0] == '.' &&
3605 (NAMLEN(ep) == 1 ||
3606 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3607 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003608 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003609 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3610 else
3611 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 break;
3615 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003619 break;
3620 }
3621 Py_DECREF(v);
3622 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003623
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624exit:
3625 if (dirp != NULL) {
3626 Py_BEGIN_ALLOW_THREADS
3627 if (fd > -1)
3628 rewinddir(dirp);
3629 closedir(dirp);
3630 Py_END_ALLOW_THREADS
3631 }
3632
3633 path_cleanup(&path);
3634
3635 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003636
Tim Peters0bb44a42000-09-15 07:44:49 +00003637#endif /* which OS */
3638} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003639
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003640#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003641/* A helper function for abspath on win32 */
3642static PyObject *
3643posix__getfullpathname(PyObject *self, PyObject *args)
3644{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003645 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 char outbuf[MAX_PATH*2];
3647 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003648 PyObject *po;
3649
3650 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3651 {
3652 wchar_t *wpath;
3653 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3654 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003655 DWORD result;
3656 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003657
3658 wpath = PyUnicode_AsUnicode(po);
3659 if (wpath == NULL)
3660 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003662 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003664 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003665 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 if (!woutbufp)
3667 return PyErr_NoMemory();
3668 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3669 }
3670 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003671 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003673 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003674 if (woutbufp != woutbuf)
3675 free(woutbufp);
3676 return v;
3677 }
3678 /* Drop the argument parsing error as narrow strings
3679 are also valid. */
3680 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003681
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003682 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3683 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003685 if (win32_warn_bytes_api())
3686 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003687 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003688 outbuf, &temp)) {
3689 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003690 return NULL;
3691 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3693 return PyUnicode_Decode(outbuf, strlen(outbuf),
3694 Py_FileSystemDefaultEncoding, NULL);
3695 }
3696 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003697} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003698
Brian Curtind25aef52011-06-13 15:16:04 -05003699
Brian Curtinf5e76d02010-11-24 13:14:05 +00003700
Brian Curtind40e6f72010-07-08 21:39:08 +00003701/* A helper function for samepath on windows */
3702static PyObject *
3703posix__getfinalpathname(PyObject *self, PyObject *args)
3704{
3705 HANDLE hFile;
3706 int buf_size;
3707 wchar_t *target_path;
3708 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003709 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003710 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003711
Victor Stinnereb5657a2011-09-30 01:44:27 +02003712 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003713 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003714 path = PyUnicode_AsUnicode(po);
3715 if (path == NULL)
3716 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003717
3718 if(!check_GetFinalPathNameByHandle()) {
3719 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3720 NotImplementedError. */
3721 return PyErr_Format(PyExc_NotImplementedError,
3722 "GetFinalPathNameByHandle not available on this platform");
3723 }
3724
3725 hFile = CreateFileW(
3726 path,
3727 0, /* desired access */
3728 0, /* share mode */
3729 NULL, /* security attributes */
3730 OPEN_EXISTING,
3731 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3732 FILE_FLAG_BACKUP_SEMANTICS,
3733 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003734
Victor Stinnereb5657a2011-09-30 01:44:27 +02003735 if(hFile == INVALID_HANDLE_VALUE)
3736 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003737
3738 /* We have a good handle to the target, use it to determine the
3739 target path name. */
3740 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3741
3742 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003743 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003744
3745 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3746 if(!target_path)
3747 return PyErr_NoMemory();
3748
3749 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3750 buf_size, VOLUME_NAME_DOS);
3751 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003752 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003753
3754 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003755 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003756
3757 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003758 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003759 free(target_path);
3760 return result;
3761
3762} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003763
3764static PyObject *
3765posix__getfileinformation(PyObject *self, PyObject *args)
3766{
3767 HANDLE hFile;
3768 BY_HANDLE_FILE_INFORMATION info;
3769 int fd;
3770
3771 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3772 return NULL;
3773
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003774 if (!_PyVerify_fd(fd))
3775 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003776
3777 hFile = (HANDLE)_get_osfhandle(fd);
3778 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003779 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003780
3781 if (!GetFileInformationByHandle(hFile, &info))
3782 return win32_error("_getfileinformation", NULL);
3783
3784 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3785 info.nFileIndexHigh,
3786 info.nFileIndexLow);
3787}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003788
Brian Curtin95d028f2011-06-09 09:10:38 -05003789PyDoc_STRVAR(posix__isdir__doc__,
3790"Return true if the pathname refers to an existing directory.");
3791
Brian Curtin9c669cc2011-06-08 18:17:18 -05003792static PyObject *
3793posix__isdir(PyObject *self, PyObject *args)
3794{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003795 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003796 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003797 DWORD attributes;
3798
3799 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003800 wchar_t *wpath = PyUnicode_AsUnicode(po);
3801 if (wpath == NULL)
3802 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003803
3804 attributes = GetFileAttributesW(wpath);
3805 if (attributes == INVALID_FILE_ATTRIBUTES)
3806 Py_RETURN_FALSE;
3807 goto check;
3808 }
3809 /* Drop the argument parsing error as narrow strings
3810 are also valid. */
3811 PyErr_Clear();
3812
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003813 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003814 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003815 if (win32_warn_bytes_api())
3816 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003817 attributes = GetFileAttributesA(path);
3818 if (attributes == INVALID_FILE_ATTRIBUTES)
3819 Py_RETURN_FALSE;
3820
3821check:
3822 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3823 Py_RETURN_TRUE;
3824 else
3825 Py_RETURN_FALSE;
3826}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003827#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003828
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003829PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003830"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3831Create a directory.\n\
3832\n\
3833If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3834 and path should be relative; path will then be relative to that directory.\n\
3835dir_fd may not be implemented on your platform.\n\
3836 If it is unavailable, using it will raise a NotImplementedError.\n\
3837\n\
3838The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003839
Barry Warsaw53699e91996-12-10 23:23:01 +00003840static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003841posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003842{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003843 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003844 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003845 int dir_fd = DEFAULT_DIR_FD;
3846 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3847 PyObject *return_value = NULL;
3848 int result;
3849
3850 memset(&path, 0, sizeof(path));
3851 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3852 path_converter, &path, &mode,
3853#ifdef HAVE_MKDIRAT
3854 dir_fd_converter, &dir_fd
3855#else
3856 dir_fd_unavailable, &dir_fd
3857#endif
3858 ))
3859 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003860
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003861#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003863 if (path.wide)
3864 result = CreateDirectoryW(path.wide, NULL);
3865 else
3866 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003867 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003868
Larry Hastings9cf065c2012-06-22 16:30:09 -07003869 if (!result) {
3870 return_value = win32_error_object("mkdir", path.object);
3871 goto exit;
3872 }
3873#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003874 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003875#if HAVE_MKDIRAT
3876 if (dir_fd != DEFAULT_DIR_FD)
3877 result = mkdirat(dir_fd, path.narrow, mode);
3878 else
3879#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003880#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003881 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003882#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003883 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003884#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003886 if (result < 0) {
3887 return_value = path_error("mkdir", &path);
3888 goto exit;
3889 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00003890#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003891 return_value = Py_None;
3892 Py_INCREF(Py_None);
3893exit:
3894 path_cleanup(&path);
3895 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003896}
3897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003898
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003899/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3900#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003901#include <sys/resource.h>
3902#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003903
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003904
3905#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003906PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003907"nice(inc) -> new_priority\n\n\
3908Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003909
Barry Warsaw53699e91996-12-10 23:23:01 +00003910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003911posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003912{
Victor Stinner8c62be82010-05-06 00:08:46 +00003913 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003914
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3916 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003917
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 /* There are two flavours of 'nice': one that returns the new
3919 priority (as required by almost all standards out there) and the
3920 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3921 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003922
Victor Stinner8c62be82010-05-06 00:08:46 +00003923 If we are of the nice family that returns the new priority, we
3924 need to clear errno before the call, and check if errno is filled
3925 before calling posix_error() on a returnvalue of -1, because the
3926 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003927
Victor Stinner8c62be82010-05-06 00:08:46 +00003928 errno = 0;
3929 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003930#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003931 if (value == 0)
3932 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003933#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 if (value == -1 && errno != 0)
3935 /* either nice() or getpriority() returned an error */
3936 return posix_error();
3937 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003938}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003939#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003940
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003941
3942#ifdef HAVE_GETPRIORITY
3943PyDoc_STRVAR(posix_getpriority__doc__,
3944"getpriority(which, who) -> current_priority\n\n\
3945Get program scheduling priority.");
3946
3947static PyObject *
3948posix_getpriority(PyObject *self, PyObject *args)
3949{
3950 int which, who, retval;
3951
3952 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3953 return NULL;
3954 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003955 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003956 if (errno != 0)
3957 return posix_error();
3958 return PyLong_FromLong((long)retval);
3959}
3960#endif /* HAVE_GETPRIORITY */
3961
3962
3963#ifdef HAVE_SETPRIORITY
3964PyDoc_STRVAR(posix_setpriority__doc__,
3965"setpriority(which, who, prio) -> None\n\n\
3966Set program scheduling priority.");
3967
3968static PyObject *
3969posix_setpriority(PyObject *self, PyObject *args)
3970{
3971 int which, who, prio, retval;
3972
3973 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3974 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003975 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003976 if (retval == -1)
3977 return posix_error();
3978 Py_RETURN_NONE;
3979}
3980#endif /* HAVE_SETPRIORITY */
3981
3982
Barry Warsaw53699e91996-12-10 23:23:01 +00003983static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003984internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003985{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986 char *function_name = is_replace ? "replace" : "rename";
3987 path_t src;
3988 path_t dst;
3989 int src_dir_fd = DEFAULT_DIR_FD;
3990 int dst_dir_fd = DEFAULT_DIR_FD;
3991 int dir_fd_specified;
3992 PyObject *return_value = NULL;
3993 char format[24];
3994 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
3995
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003996#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003997 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003998 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003999#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004000 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004001#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004002
4003 memset(&src, 0, sizeof(src));
4004 memset(&dst, 0, sizeof(dst));
4005 strcpy(format, "O&O&|$O&O&:");
4006 strcat(format, function_name);
4007 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4008 path_converter, &src,
4009 path_converter, &dst,
4010 dir_fd_converter, &src_dir_fd,
4011 dir_fd_converter, &dst_dir_fd))
4012 return NULL;
4013
4014 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4015 (dst_dir_fd != DEFAULT_DIR_FD);
4016#ifndef HAVE_RENAMEAT
4017 if (dir_fd_specified) {
4018 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4019 goto exit;
4020 }
4021#endif
4022
4023 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4024 PyErr_Format(PyExc_ValueError,
4025 "%s: src and dst must be the same type", function_name);
4026 goto exit;
4027 }
4028
4029#ifdef MS_WINDOWS
4030 Py_BEGIN_ALLOW_THREADS
4031 if (src.wide)
4032 result = MoveFileExW(src.wide, dst.wide, flags);
4033 else
4034 result = MoveFileExA(src.narrow, dst.narrow, flags);
4035 Py_END_ALLOW_THREADS
4036
4037 if (!result) {
4038 return_value = win32_error_object(function_name, dst.object);
4039 goto exit;
4040 }
4041
4042#else
4043 Py_BEGIN_ALLOW_THREADS
4044#ifdef HAVE_RENAMEAT
4045 if (dir_fd_specified)
4046 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4047 else
4048#endif
4049 result = rename(src.narrow, dst.narrow);
4050 Py_END_ALLOW_THREADS
4051
4052 if (result) {
4053 return_value = path_error(function_name, &dst);
4054 goto exit;
4055 }
4056#endif
4057
4058 Py_INCREF(Py_None);
4059 return_value = Py_None;
4060exit:
4061 path_cleanup(&src);
4062 path_cleanup(&dst);
4063 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004064}
4065
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004066PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004067"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4068Rename a file or directory.\n\
4069\n\
4070If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4071 descriptor open to a directory, and the respective path string (src or dst)\n\
4072 should be relative; the path will then be relative to that directory.\n\
4073src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4074 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004075
4076static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004077posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004078{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004079 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004080}
4081
4082PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004083"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4084Rename a file or directory, overwriting the destination.\n\
4085\n\
4086If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4087 descriptor open to a directory, and the respective path string (src or dst)\n\
4088 should be relative; the path will then be relative to that directory.\n\
4089src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4090 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004091
4092static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004094{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004096}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004098PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004099"rmdir(path, *, dir_fd=None)\n\n\
4100Remove a directory.\n\
4101\n\
4102If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4103 and path should be relative; path will then be relative to that directory.\n\
4104dir_fd may not be implemented on your platform.\n\
4105 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004106
Barry Warsaw53699e91996-12-10 23:23:01 +00004107static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004108posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004109{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004110 path_t path;
4111 int dir_fd = DEFAULT_DIR_FD;
4112 static char *keywords[] = {"path", "dir_fd", NULL};
4113 int result;
4114 PyObject *return_value = NULL;
4115
4116 memset(&path, 0, sizeof(path));
4117 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4118 path_converter, &path,
4119#ifdef HAVE_UNLINKAT
4120 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004121#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004122 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004123#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004124 ))
4125 return NULL;
4126
4127 Py_BEGIN_ALLOW_THREADS
4128#ifdef MS_WINDOWS
4129 if (path.wide)
4130 result = RemoveDirectoryW(path.wide);
4131 else
4132 result = RemoveDirectoryA(path.narrow);
4133 result = !result; /* Windows, success=1, UNIX, success=0 */
4134#else
4135#ifdef HAVE_UNLINKAT
4136 if (dir_fd != DEFAULT_DIR_FD)
4137 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4138 else
4139#endif
4140 result = rmdir(path.narrow);
4141#endif
4142 Py_END_ALLOW_THREADS
4143
4144 if (result) {
4145 return_value = path_error("rmdir", &path);
4146 goto exit;
4147 }
4148
4149 return_value = Py_None;
4150 Py_INCREF(Py_None);
4151
4152exit:
4153 path_cleanup(&path);
4154 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004155}
4156
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004157
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004158#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004159PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004160"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004161Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004162
Barry Warsaw53699e91996-12-10 23:23:01 +00004163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004164posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004165{
Victor Stinner8c62be82010-05-06 00:08:46 +00004166 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004167#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004168 wchar_t *command;
4169 if (!PyArg_ParseTuple(args, "u:system", &command))
4170 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004171
Victor Stinner8c62be82010-05-06 00:08:46 +00004172 Py_BEGIN_ALLOW_THREADS
4173 sts = _wsystem(command);
4174 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004175#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004176 PyObject *command_obj;
4177 char *command;
4178 if (!PyArg_ParseTuple(args, "O&:system",
4179 PyUnicode_FSConverter, &command_obj))
4180 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004181
Victor Stinner8c62be82010-05-06 00:08:46 +00004182 command = PyBytes_AsString(command_obj);
4183 Py_BEGIN_ALLOW_THREADS
4184 sts = system(command);
4185 Py_END_ALLOW_THREADS
4186 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004187#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004188 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004189}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004190#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004191
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004192
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004193PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004194"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004195Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004196
Barry Warsaw53699e91996-12-10 23:23:01 +00004197static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004198posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004199{
Victor Stinner8c62be82010-05-06 00:08:46 +00004200 int i;
4201 if (!PyArg_ParseTuple(args, "i:umask", &i))
4202 return NULL;
4203 i = (int)umask(i);
4204 if (i < 0)
4205 return posix_error();
4206 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004207}
4208
Brian Curtind40e6f72010-07-08 21:39:08 +00004209#ifdef MS_WINDOWS
4210
4211/* override the default DeleteFileW behavior so that directory
4212symlinks can be removed with this function, the same as with
4213Unix symlinks */
4214BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4215{
4216 WIN32_FILE_ATTRIBUTE_DATA info;
4217 WIN32_FIND_DATAW find_data;
4218 HANDLE find_data_handle;
4219 int is_directory = 0;
4220 int is_link = 0;
4221
4222 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4223 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004224
Brian Curtind40e6f72010-07-08 21:39:08 +00004225 /* Get WIN32_FIND_DATA structure for the path to determine if
4226 it is a symlink */
4227 if(is_directory &&
4228 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4229 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4230
4231 if(find_data_handle != INVALID_HANDLE_VALUE) {
4232 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4233 FindClose(find_data_handle);
4234 }
4235 }
4236 }
4237
4238 if (is_directory && is_link)
4239 return RemoveDirectoryW(lpFileName);
4240
4241 return DeleteFileW(lpFileName);
4242}
4243#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004245PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004246"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004247Remove a file (same as remove()).\n\
4248\n\
4249If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4250 and path should be relative; path will then be relative to that directory.\n\
4251dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004252 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004253
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004254PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004255"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004256Remove a file (same as unlink()).\n\
4257\n\
4258If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4259 and path should be relative; path will then be relative to that directory.\n\
4260dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004261 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004262
Barry Warsaw53699e91996-12-10 23:23:01 +00004263static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004264posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004265{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004266 path_t path;
4267 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004268 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004269 int result;
4270 PyObject *return_value = NULL;
4271
4272 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004273 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004274 path_converter, &path,
4275#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004276 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004277#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004278 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004279#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004280 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004281 return NULL;
4282
4283 Py_BEGIN_ALLOW_THREADS
4284#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004285 if (path.wide)
4286 result = Py_DeleteFileW(path.wide);
4287 else
4288 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004289 result = !result; /* Windows, success=1, UNIX, success=0 */
4290#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004291#ifdef HAVE_UNLINKAT
4292 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004293 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004294 else
4295#endif /* HAVE_UNLINKAT */
4296 result = unlink(path.narrow);
4297#endif
4298 Py_END_ALLOW_THREADS
4299
4300 if (result) {
4301 return_value = path_error("unlink", &path);
4302 goto exit;
4303 }
4304
4305 return_value = Py_None;
4306 Py_INCREF(Py_None);
4307
4308exit:
4309 path_cleanup(&path);
4310 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004311}
4312
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004314PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004315"uname() -> uname_result\n\n\
4316Return an object identifying the current operating system.\n\
4317The object behaves like a named tuple with the following fields:\n\
4318 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004319
Larry Hastings605a62d2012-06-24 04:33:36 -07004320static PyStructSequence_Field uname_result_fields[] = {
4321 {"sysname", "operating system name"},
4322 {"nodename", "name of machine on network (implementation-defined)"},
4323 {"release", "operating system release"},
4324 {"version", "operating system version"},
4325 {"machine", "hardware identifier"},
4326 {NULL}
4327};
4328
4329PyDoc_STRVAR(uname_result__doc__,
4330"uname_result: Result from os.uname().\n\n\
4331This object may be accessed either as a tuple of\n\
4332 (sysname, nodename, release, version, machine),\n\
4333or via the attributes sysname, nodename, release, version, and machine.\n\
4334\n\
4335See os.uname for more information.");
4336
4337static PyStructSequence_Desc uname_result_desc = {
4338 "uname_result", /* name */
4339 uname_result__doc__, /* doc */
4340 uname_result_fields,
4341 5
4342};
4343
4344static PyTypeObject UnameResultType;
4345
4346
4347#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004348static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004349posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004350{
Victor Stinner8c62be82010-05-06 00:08:46 +00004351 struct utsname u;
4352 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004353 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004354
Victor Stinner8c62be82010-05-06 00:08:46 +00004355 Py_BEGIN_ALLOW_THREADS
4356 res = uname(&u);
4357 Py_END_ALLOW_THREADS
4358 if (res < 0)
4359 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004360
4361 value = PyStructSequence_New(&UnameResultType);
4362 if (value == NULL)
4363 return NULL;
4364
4365#define SET(i, field) \
4366 { \
4367 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4368 if (!o) { \
4369 Py_DECREF(value); \
4370 return NULL; \
4371 } \
4372 PyStructSequence_SET_ITEM(value, i, o); \
4373 } \
4374
4375 SET(0, u.sysname);
4376 SET(1, u.nodename);
4377 SET(2, u.release);
4378 SET(3, u.version);
4379 SET(4, u.machine);
4380
4381#undef SET
4382
4383 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004384}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004385#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004386
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004387
Larry Hastings9cf065c2012-06-22 16:30:09 -07004388PyDoc_STRVAR(posix_utime__doc__,
4389"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4390Set the access and modified time of path.\n\
4391\n\
4392path may always be specified as a string.\n\
4393On some platforms, path may also be specified as an open file descriptor.\n\
4394 If this functionality is unavailable, using it raises an exception.\n\
4395\n\
4396If times is not None, it must be a tuple (atime, mtime);\n\
4397 atime and mtime should be expressed as float seconds since the epoch.\n\
4398If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4399 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4400 since the epoch.\n\
4401If both times and ns are None, utime uses the current time.\n\
4402Specifying tuples for both times and ns is an error.\n\
4403\n\
4404If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4405 and path should be relative; path will then be relative to that directory.\n\
4406If follow_symlinks is False, and the last element of the path is a symbolic\n\
4407 link, utime will modify the symbolic link itself instead of the file the\n\
4408 link points to.\n\
4409It is an error to use dir_fd or follow_symlinks when specifying path\n\
4410 as an open file descriptor.\n\
4411dir_fd and follow_symlinks may not be available on your platform.\n\
4412 If they are unavailable, using them will raise a NotImplementedError.");
4413
4414typedef struct {
4415 int now;
4416 time_t atime_s;
4417 long atime_ns;
4418 time_t mtime_s;
4419 long mtime_ns;
4420} utime_t;
4421
4422/*
4423 * these macros assume that "utime" is a pointer to a utime_t
4424 * they also intentionally leak the declaration of a pointer named "time"
4425 */
4426#define UTIME_TO_TIMESPEC \
4427 struct timespec ts[2]; \
4428 struct timespec *time; \
4429 if (utime->now) \
4430 time = NULL; \
4431 else { \
4432 ts[0].tv_sec = utime->atime_s; \
4433 ts[0].tv_nsec = utime->atime_ns; \
4434 ts[1].tv_sec = utime->mtime_s; \
4435 ts[1].tv_nsec = utime->mtime_ns; \
4436 time = ts; \
4437 } \
4438
4439#define UTIME_TO_TIMEVAL \
4440 struct timeval tv[2]; \
4441 struct timeval *time; \
4442 if (utime->now) \
4443 time = NULL; \
4444 else { \
4445 tv[0].tv_sec = utime->atime_s; \
4446 tv[0].tv_usec = utime->atime_ns / 1000; \
4447 tv[1].tv_sec = utime->mtime_s; \
4448 tv[1].tv_usec = utime->mtime_ns / 1000; \
4449 time = tv; \
4450 } \
4451
4452#define UTIME_TO_UTIMBUF \
4453 struct utimbuf u[2]; \
4454 struct utimbuf *time; \
4455 if (utime->now) \
4456 time = NULL; \
4457 else { \
4458 u.actime = utime->atime_s; \
4459 u.modtime = utime->mtime_s; \
4460 time = u; \
4461 }
4462
4463#define UTIME_TO_TIME_T \
4464 time_t timet[2]; \
4465 struct timet time; \
4466 if (utime->now) \
4467 time = NULL; \
4468 else { \
4469 timet[0] = utime->atime_s; \
4470 timet[1] = utime->mtime_s; \
4471 time = &timet; \
4472 } \
4473
4474
4475#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4476
4477#if UTIME_HAVE_DIR_FD
4478
4479static int
4480utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4481{
4482#ifdef HAVE_UTIMENSAT
4483 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4484 UTIME_TO_TIMESPEC;
4485 return utimensat(dir_fd, path, time, flags);
4486#elif defined(HAVE_FUTIMESAT)
4487 UTIME_TO_TIMEVAL;
4488 /*
4489 * follow_symlinks will never be false here;
4490 * we only allow !follow_symlinks and dir_fd together
4491 * if we have utimensat()
4492 */
4493 assert(follow_symlinks);
4494 return futimesat(dir_fd, path, time);
4495#endif
4496}
4497
4498#endif
4499
4500#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4501
4502#if UTIME_HAVE_FD
4503
4504static int
4505utime_fd(utime_t *utime, int fd)
4506{
4507#ifdef HAVE_FUTIMENS
4508 UTIME_TO_TIMESPEC;
4509 return futimens(fd, time);
4510#else
4511 UTIME_TO_TIMEVAL;
4512 return futimes(fd, time);
4513#endif
4514}
4515
4516#endif
4517
4518
4519#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4520 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4521
4522#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4523
4524static int
4525utime_nofollow_symlinks(utime_t *utime, char *path)
4526{
4527#ifdef HAVE_UTIMENSAT
4528 UTIME_TO_TIMESPEC;
4529 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4530#else
4531 UTIME_TO_TIMEVAL;
4532 return lutimes(path, time);
4533#endif
4534}
4535
4536#endif
4537
4538#ifndef MS_WINDOWS
4539
4540static int
4541utime_default(utime_t *utime, char *path)
4542{
4543#ifdef HAVE_UTIMENSAT
4544 UTIME_TO_TIMESPEC;
4545 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4546#elif defined(HAVE_UTIMES)
4547 UTIME_TO_TIMEVAL;
4548 return utimes(path, time);
4549#elif defined(HAVE_UTIME_H)
4550 UTIME_TO_UTIMBUF;
4551 return utime(path, time);
4552#else
4553 UTIME_TO_TIME_T;
4554 return utime(path, time);
4555#endif
4556}
4557
4558#endif
4559
Larry Hastings76ad59b2012-05-03 00:30:07 -07004560static int
4561split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4562{
4563 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004564 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004565 divmod = PyNumber_Divmod(py_long, billion);
4566 if (!divmod)
4567 goto exit;
4568 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4569 if ((*s == -1) && PyErr_Occurred())
4570 goto exit;
4571 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004572 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004573 goto exit;
4574
4575 result = 1;
4576exit:
4577 Py_XDECREF(divmod);
4578 return result;
4579}
4580
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581static PyObject *
4582posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004583{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004585 PyObject *times = NULL;
4586 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587 int dir_fd = DEFAULT_DIR_FD;
4588 int follow_symlinks = 1;
4589 char *keywords[] = {"path", "times", "ns", "dir_fd",
4590 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004591
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004593
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594#ifdef MS_WINDOWS
4595 HANDLE hFile;
4596 FILETIME atime, mtime;
4597#else
4598 int result;
4599#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004600
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004602
Larry Hastings9cf065c2012-06-22 16:30:09 -07004603 memset(&path, 0, sizeof(path));
4604#if UTIME_HAVE_FD
4605 path.allow_fd = 1;
4606#endif
4607 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4608 "O&|O$OO&p:utime", keywords,
4609 path_converter, &path,
4610 &times, &ns,
4611#if UTIME_HAVE_DIR_FD
4612 dir_fd_converter, &dir_fd,
4613#else
4614 dir_fd_unavailable, &dir_fd,
4615#endif
4616 &follow_symlinks
4617 ))
4618 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004619
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620 if (times && (times != Py_None) && ns) {
4621 PyErr_SetString(PyExc_ValueError,
4622 "utime: you may specify either 'times'"
4623 " or 'ns' but not both");
4624 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004625 }
4626
4627 if (times && (times != Py_None)) {
4628 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629 PyErr_SetString(PyExc_TypeError,
4630 "utime: 'times' must be either"
4631 " a tuple of two ints or None");
4632 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004633 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004635 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004637 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004638 &utime.mtime_s, &utime.mtime_ns) == -1) {
4639 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004640 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004641 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004642 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004643 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004644 PyErr_SetString(PyExc_TypeError,
4645 "utime: 'ns' must be a tuple of two ints");
4646 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004647 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004648 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004649 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004650 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004651 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652 &utime.mtime_s, &utime.mtime_ns)) {
4653 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004654 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004655 }
4656 else {
4657 /* times and ns are both None/unspecified. use "now". */
4658 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004659 }
4660
Larry Hastings9cf065c2012-06-22 16:30:09 -07004661#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4662 if (follow_symlinks_specified("utime", follow_symlinks))
4663 goto exit;
4664#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004665
Larry Hastings9cf065c2012-06-22 16:30:09 -07004666 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4667 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4668 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4669 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004670
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671#if !defined(HAVE_UTIMENSAT)
4672 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004673 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004674 "utime: cannot use dir_fd and follow_symlinks "
4675 "together on this platform");
4676 goto exit;
4677 }
4678#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004679
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004680#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004681 Py_BEGIN_ALLOW_THREADS
4682 if (path.wide)
4683 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004684 NULL, OPEN_EXISTING,
4685 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004686 else
4687 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004688 NULL, OPEN_EXISTING,
4689 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 Py_END_ALLOW_THREADS
4691 if (hFile == INVALID_HANDLE_VALUE) {
4692 win32_error_object("utime", path.object);
4693 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004694 }
4695
Larry Hastings9cf065c2012-06-22 16:30:09 -07004696 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004697 SYSTEMTIME now;
4698 GetSystemTime(&now);
4699 if (!SystemTimeToFileTime(&now, &mtime) ||
4700 !SystemTimeToFileTime(&now, &atime)) {
4701 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004703 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004704 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004705 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4707 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004708 }
4709 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4710 /* Avoid putting the file name into the error here,
4711 as that may confuse the user into believing that
4712 something is wrong with the file, when it also
4713 could be the time stamp that gives a problem. */
4714 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004716 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004717#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004718 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004719
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4721 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4722 result = utime_nofollow_symlinks(&utime, path.narrow);
4723 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004724#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725
4726#if UTIME_HAVE_DIR_FD
4727 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4728 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4729 else
4730#endif
4731
4732#if UTIME_HAVE_FD
4733 if (path.fd != -1)
4734 result = utime_fd(&utime, path.fd);
4735 else
4736#endif
4737
4738 result = utime_default(&utime, path.narrow);
4739
4740 Py_END_ALLOW_THREADS
4741
4742 if (result < 0) {
4743 /* see previous comment about not putting filename in error here */
4744 return_value = posix_error();
4745 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004746 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004747
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004748#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004749
4750 Py_INCREF(Py_None);
4751 return_value = Py_None;
4752
4753exit:
4754 path_cleanup(&path);
4755#ifdef MS_WINDOWS
4756 if (hFile != INVALID_HANDLE_VALUE)
4757 CloseHandle(hFile);
4758#endif
4759 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004760}
4761
Guido van Rossum3b066191991-06-04 19:40:25 +00004762/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004763
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004764PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004765"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004766Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004767
Barry Warsaw53699e91996-12-10 23:23:01 +00004768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004769posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004770{
Victor Stinner8c62be82010-05-06 00:08:46 +00004771 int sts;
4772 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4773 return NULL;
4774 _exit(sts);
4775 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004776}
4777
Martin v. Löwis114619e2002-10-07 06:44:21 +00004778#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4779static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004780free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004781{
Victor Stinner8c62be82010-05-06 00:08:46 +00004782 Py_ssize_t i;
4783 for (i = 0; i < count; i++)
4784 PyMem_Free(array[i]);
4785 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004786}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004787
Antoine Pitrou69f71142009-05-24 21:25:49 +00004788static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004789int fsconvert_strdup(PyObject *o, char**out)
4790{
Victor Stinner8c62be82010-05-06 00:08:46 +00004791 PyObject *bytes;
4792 Py_ssize_t size;
4793 if (!PyUnicode_FSConverter(o, &bytes))
4794 return 0;
4795 size = PyBytes_GET_SIZE(bytes);
4796 *out = PyMem_Malloc(size+1);
4797 if (!*out)
4798 return 0;
4799 memcpy(*out, PyBytes_AsString(bytes), size+1);
4800 Py_DECREF(bytes);
4801 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004802}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004803#endif
4804
Ross Lagerwall7807c352011-03-17 20:20:30 +02004805#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004806static char**
4807parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4808{
Victor Stinner8c62be82010-05-06 00:08:46 +00004809 char **envlist;
4810 Py_ssize_t i, pos, envc;
4811 PyObject *keys=NULL, *vals=NULL;
4812 PyObject *key, *val, *key2, *val2;
4813 char *p, *k, *v;
4814 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004815
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 i = PyMapping_Size(env);
4817 if (i < 0)
4818 return NULL;
4819 envlist = PyMem_NEW(char *, i + 1);
4820 if (envlist == NULL) {
4821 PyErr_NoMemory();
4822 return NULL;
4823 }
4824 envc = 0;
4825 keys = PyMapping_Keys(env);
4826 vals = PyMapping_Values(env);
4827 if (!keys || !vals)
4828 goto error;
4829 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4830 PyErr_Format(PyExc_TypeError,
4831 "env.keys() or env.values() is not a list");
4832 goto error;
4833 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004834
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 for (pos = 0; pos < i; pos++) {
4836 key = PyList_GetItem(keys, pos);
4837 val = PyList_GetItem(vals, pos);
4838 if (!key || !val)
4839 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004840
Victor Stinner8c62be82010-05-06 00:08:46 +00004841 if (PyUnicode_FSConverter(key, &key2) == 0)
4842 goto error;
4843 if (PyUnicode_FSConverter(val, &val2) == 0) {
4844 Py_DECREF(key2);
4845 goto error;
4846 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004847
4848#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004849 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4850 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004851#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004852 k = PyBytes_AsString(key2);
4853 v = PyBytes_AsString(val2);
4854 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004855
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 p = PyMem_NEW(char, len);
4857 if (p == NULL) {
4858 PyErr_NoMemory();
4859 Py_DECREF(key2);
4860 Py_DECREF(val2);
4861 goto error;
4862 }
4863 PyOS_snprintf(p, len, "%s=%s", k, v);
4864 envlist[envc++] = p;
4865 Py_DECREF(key2);
4866 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004867#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004868 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004869#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004870 }
4871 Py_DECREF(vals);
4872 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004873
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 envlist[envc] = 0;
4875 *envc_ptr = envc;
4876 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004877
4878error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004879 Py_XDECREF(keys);
4880 Py_XDECREF(vals);
4881 while (--envc >= 0)
4882 PyMem_DEL(envlist[envc]);
4883 PyMem_DEL(envlist);
4884 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004885}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004886
Ross Lagerwall7807c352011-03-17 20:20:30 +02004887static char**
4888parse_arglist(PyObject* argv, Py_ssize_t *argc)
4889{
4890 int i;
4891 char **argvlist = PyMem_NEW(char *, *argc+1);
4892 if (argvlist == NULL) {
4893 PyErr_NoMemory();
4894 return NULL;
4895 }
4896 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004897 PyObject* item = PySequence_ITEM(argv, i);
4898 if (item == NULL)
4899 goto fail;
4900 if (!fsconvert_strdup(item, &argvlist[i])) {
4901 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004902 goto fail;
4903 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004904 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004905 }
4906 argvlist[*argc] = NULL;
4907 return argvlist;
4908fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004909 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004910 free_string_array(argvlist, *argc);
4911 return NULL;
4912}
4913#endif
4914
4915#ifdef HAVE_EXECV
4916PyDoc_STRVAR(posix_execv__doc__,
4917"execv(path, args)\n\n\
4918Execute an executable path with arguments, replacing current process.\n\
4919\n\
4920 path: path of executable file\n\
4921 args: tuple or list of strings");
4922
4923static PyObject *
4924posix_execv(PyObject *self, PyObject *args)
4925{
4926 PyObject *opath;
4927 char *path;
4928 PyObject *argv;
4929 char **argvlist;
4930 Py_ssize_t argc;
4931
4932 /* execv has two arguments: (path, argv), where
4933 argv is a list or tuple of strings. */
4934
4935 if (!PyArg_ParseTuple(args, "O&O:execv",
4936 PyUnicode_FSConverter,
4937 &opath, &argv))
4938 return NULL;
4939 path = PyBytes_AsString(opath);
4940 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4941 PyErr_SetString(PyExc_TypeError,
4942 "execv() arg 2 must be a tuple or list");
4943 Py_DECREF(opath);
4944 return NULL;
4945 }
4946 argc = PySequence_Size(argv);
4947 if (argc < 1) {
4948 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4949 Py_DECREF(opath);
4950 return NULL;
4951 }
4952
4953 argvlist = parse_arglist(argv, &argc);
4954 if (argvlist == NULL) {
4955 Py_DECREF(opath);
4956 return NULL;
4957 }
4958
4959 execv(path, argvlist);
4960
4961 /* If we get here it's definitely an error */
4962
4963 free_string_array(argvlist, argc);
4964 Py_DECREF(opath);
4965 return posix_error();
4966}
4967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004968PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004969"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970Execute a path with arguments and environment, replacing current process.\n\
4971\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 path: path of executable file\n\
4973 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004974 env: dictionary of strings mapping to strings\n\
4975\n\
4976On some platforms, you may specify an open file descriptor for path;\n\
4977 execve will execute the program the file descriptor is open to.\n\
4978 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004979
Barry Warsaw53699e91996-12-10 23:23:01 +00004980static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004981posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004982{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004983 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004985 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004987 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004988 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004989
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 /* execve has three arguments: (path, argv, env), where
4991 argv is a list or tuple of strings and env is a dictionary
4992 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004993
Larry Hastings9cf065c2012-06-22 16:30:09 -07004994 memset(&path, 0, sizeof(path));
4995#ifdef HAVE_FEXECVE
4996 path.allow_fd = 1;
4997#endif
4998 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
4999 path_converter, &path,
5000 &argv, &env
5001 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005003
Ross Lagerwall7807c352011-03-17 20:20:30 +02005004 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005006 "execve: argv must be a tuple or list");
5007 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005008 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005009 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005010 if (!PyMapping_Check(env)) {
5011 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005012 "execve: environment must be a mapping object");
5013 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005015
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005018 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005020
Victor Stinner8c62be82010-05-06 00:08:46 +00005021 envlist = parse_envlist(env, &envc);
5022 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005023 goto fail;
5024
Larry Hastings9cf065c2012-06-22 16:30:09 -07005025#ifdef HAVE_FEXECVE
5026 if (path.fd > -1)
5027 fexecve(path.fd, argvlist, envlist);
5028 else
5029#endif
5030 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005031
5032 /* If we get here it's definitely an error */
5033
Larry Hastings9cf065c2012-06-22 16:30:09 -07005034 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005035
5036 while (--envc >= 0)
5037 PyMem_DEL(envlist[envc]);
5038 PyMem_DEL(envlist);
5039 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005040 if (argvlist)
5041 free_string_array(argvlist, argc);
5042 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043 return NULL;
5044}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005045#endif /* HAVE_EXECV */
5046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005047
Guido van Rossuma1065681999-01-25 23:20:23 +00005048#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005049PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005050"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005051Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005052\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 mode: mode of process creation\n\
5054 path: path of executable file\n\
5055 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005056
5057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005058posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005059{
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 PyObject *opath;
5061 char *path;
5062 PyObject *argv;
5063 char **argvlist;
5064 int mode, i;
5065 Py_ssize_t argc;
5066 Py_intptr_t spawnval;
5067 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005068
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 /* spawnv has three arguments: (mode, path, argv), where
5070 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005071
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5073 PyUnicode_FSConverter,
5074 &opath, &argv))
5075 return NULL;
5076 path = PyBytes_AsString(opath);
5077 if (PyList_Check(argv)) {
5078 argc = PyList_Size(argv);
5079 getitem = PyList_GetItem;
5080 }
5081 else if (PyTuple_Check(argv)) {
5082 argc = PyTuple_Size(argv);
5083 getitem = PyTuple_GetItem;
5084 }
5085 else {
5086 PyErr_SetString(PyExc_TypeError,
5087 "spawnv() arg 2 must be a tuple or list");
5088 Py_DECREF(opath);
5089 return NULL;
5090 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005091
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 argvlist = PyMem_NEW(char *, argc+1);
5093 if (argvlist == NULL) {
5094 Py_DECREF(opath);
5095 return PyErr_NoMemory();
5096 }
5097 for (i = 0; i < argc; i++) {
5098 if (!fsconvert_strdup((*getitem)(argv, i),
5099 &argvlist[i])) {
5100 free_string_array(argvlist, i);
5101 PyErr_SetString(
5102 PyExc_TypeError,
5103 "spawnv() arg 2 must contain only strings");
5104 Py_DECREF(opath);
5105 return NULL;
5106 }
5107 }
5108 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005109
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005110#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 Py_BEGIN_ALLOW_THREADS
5112 spawnval = spawnv(mode, path, argvlist);
5113 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005114#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 if (mode == _OLD_P_OVERLAY)
5116 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005117
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 Py_BEGIN_ALLOW_THREADS
5119 spawnval = _spawnv(mode, path, argvlist);
5120 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005121#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005122
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 free_string_array(argvlist, argc);
5124 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 if (spawnval == -1)
5127 return posix_error();
5128 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005129#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005131#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005133#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005134}
5135
5136
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005137PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005138"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005139Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005140\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 mode: mode of process creation\n\
5142 path: path of executable file\n\
5143 args: tuple or list of arguments\n\
5144 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005145
5146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005147posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005148{
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 PyObject *opath;
5150 char *path;
5151 PyObject *argv, *env;
5152 char **argvlist;
5153 char **envlist;
5154 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005155 int mode;
5156 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 Py_intptr_t spawnval;
5158 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5159 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005160
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 /* spawnve has four arguments: (mode, path, argv, env), where
5162 argv is a list or tuple of strings and env is a dictionary
5163 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005164
Victor Stinner8c62be82010-05-06 00:08:46 +00005165 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5166 PyUnicode_FSConverter,
5167 &opath, &argv, &env))
5168 return NULL;
5169 path = PyBytes_AsString(opath);
5170 if (PyList_Check(argv)) {
5171 argc = PyList_Size(argv);
5172 getitem = PyList_GetItem;
5173 }
5174 else if (PyTuple_Check(argv)) {
5175 argc = PyTuple_Size(argv);
5176 getitem = PyTuple_GetItem;
5177 }
5178 else {
5179 PyErr_SetString(PyExc_TypeError,
5180 "spawnve() arg 2 must be a tuple or list");
5181 goto fail_0;
5182 }
5183 if (!PyMapping_Check(env)) {
5184 PyErr_SetString(PyExc_TypeError,
5185 "spawnve() arg 3 must be a mapping object");
5186 goto fail_0;
5187 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005188
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 argvlist = PyMem_NEW(char *, argc+1);
5190 if (argvlist == NULL) {
5191 PyErr_NoMemory();
5192 goto fail_0;
5193 }
5194 for (i = 0; i < argc; i++) {
5195 if (!fsconvert_strdup((*getitem)(argv, i),
5196 &argvlist[i]))
5197 {
5198 lastarg = i;
5199 goto fail_1;
5200 }
5201 }
5202 lastarg = argc;
5203 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 envlist = parse_envlist(env, &envc);
5206 if (envlist == NULL)
5207 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005208
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005209#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 Py_BEGIN_ALLOW_THREADS
5211 spawnval = spawnve(mode, path, argvlist, envlist);
5212 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005213#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 if (mode == _OLD_P_OVERLAY)
5215 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005216
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 Py_BEGIN_ALLOW_THREADS
5218 spawnval = _spawnve(mode, path, argvlist, envlist);
5219 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005220#endif
Tim Peters25059d32001-12-07 20:35:43 +00005221
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 if (spawnval == -1)
5223 (void) posix_error();
5224 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005225#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005227#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005229#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005230
Victor Stinner8c62be82010-05-06 00:08:46 +00005231 while (--envc >= 0)
5232 PyMem_DEL(envlist[envc]);
5233 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005234 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005235 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005236 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005237 Py_DECREF(opath);
5238 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005239}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005240
5241/* OS/2 supports spawnvp & spawnvpe natively */
5242#if defined(PYOS_OS2)
5243PyDoc_STRVAR(posix_spawnvp__doc__,
5244"spawnvp(mode, file, args)\n\n\
5245Execute the program 'file' in a new process, using the environment\n\
5246search path to find the file.\n\
5247\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 mode: mode of process creation\n\
5249 file: executable file name\n\
5250 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005251
5252static PyObject *
5253posix_spawnvp(PyObject *self, PyObject *args)
5254{
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 PyObject *opath;
5256 char *path;
5257 PyObject *argv;
5258 char **argvlist;
5259 int mode, i, argc;
5260 Py_intptr_t spawnval;
5261 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005262
Victor Stinner8c62be82010-05-06 00:08:46 +00005263 /* spawnvp has three arguments: (mode, path, argv), where
5264 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005265
Victor Stinner8c62be82010-05-06 00:08:46 +00005266 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5267 PyUnicode_FSConverter,
5268 &opath, &argv))
5269 return NULL;
5270 path = PyBytes_AsString(opath);
5271 if (PyList_Check(argv)) {
5272 argc = PyList_Size(argv);
5273 getitem = PyList_GetItem;
5274 }
5275 else if (PyTuple_Check(argv)) {
5276 argc = PyTuple_Size(argv);
5277 getitem = PyTuple_GetItem;
5278 }
5279 else {
5280 PyErr_SetString(PyExc_TypeError,
5281 "spawnvp() arg 2 must be a tuple or list");
5282 Py_DECREF(opath);
5283 return NULL;
5284 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005285
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 argvlist = PyMem_NEW(char *, argc+1);
5287 if (argvlist == NULL) {
5288 Py_DECREF(opath);
5289 return PyErr_NoMemory();
5290 }
5291 for (i = 0; i < argc; i++) {
5292 if (!fsconvert_strdup((*getitem)(argv, i),
5293 &argvlist[i])) {
5294 free_string_array(argvlist, i);
5295 PyErr_SetString(
5296 PyExc_TypeError,
5297 "spawnvp() arg 2 must contain only strings");
5298 Py_DECREF(opath);
5299 return NULL;
5300 }
5301 }
5302 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005303
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005305#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005307#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005309#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005311
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 free_string_array(argvlist, argc);
5313 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005314
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 if (spawnval == -1)
5316 return posix_error();
5317 else
5318 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005319}
5320
5321
5322PyDoc_STRVAR(posix_spawnvpe__doc__,
5323"spawnvpe(mode, file, args, env)\n\n\
5324Execute the program 'file' in a new process, using the environment\n\
5325search path to find the file.\n\
5326\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 mode: mode of process creation\n\
5328 file: executable file name\n\
5329 args: tuple or list of arguments\n\
5330 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005331
5332static PyObject *
5333posix_spawnvpe(PyObject *self, PyObject *args)
5334{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005335 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005336 char *path;
5337 PyObject *argv, *env;
5338 char **argvlist;
5339 char **envlist;
5340 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005341 int mode;
5342 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 Py_intptr_t spawnval;
5344 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5345 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005346
Victor Stinner8c62be82010-05-06 00:08:46 +00005347 /* spawnvpe has four arguments: (mode, path, argv, env), where
5348 argv is a list or tuple of strings and env is a dictionary
5349 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005350
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5352 PyUnicode_FSConverter,
5353 &opath, &argv, &env))
5354 return NULL;
5355 path = PyBytes_AsString(opath);
5356 if (PyList_Check(argv)) {
5357 argc = PyList_Size(argv);
5358 getitem = PyList_GetItem;
5359 }
5360 else if (PyTuple_Check(argv)) {
5361 argc = PyTuple_Size(argv);
5362 getitem = PyTuple_GetItem;
5363 }
5364 else {
5365 PyErr_SetString(PyExc_TypeError,
5366 "spawnvpe() arg 2 must be a tuple or list");
5367 goto fail_0;
5368 }
5369 if (!PyMapping_Check(env)) {
5370 PyErr_SetString(PyExc_TypeError,
5371 "spawnvpe() arg 3 must be a mapping object");
5372 goto fail_0;
5373 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005374
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 argvlist = PyMem_NEW(char *, argc+1);
5376 if (argvlist == NULL) {
5377 PyErr_NoMemory();
5378 goto fail_0;
5379 }
5380 for (i = 0; i < argc; i++) {
5381 if (!fsconvert_strdup((*getitem)(argv, i),
5382 &argvlist[i]))
5383 {
5384 lastarg = i;
5385 goto fail_1;
5386 }
5387 }
5388 lastarg = argc;
5389 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005390
Victor Stinner8c62be82010-05-06 00:08:46 +00005391 envlist = parse_envlist(env, &envc);
5392 if (envlist == NULL)
5393 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005394
Victor Stinner8c62be82010-05-06 00:08:46 +00005395 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005396#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005397 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005398#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005399 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005400#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005401 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005402
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 if (spawnval == -1)
5404 (void) posix_error();
5405 else
5406 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005407
Victor Stinner8c62be82010-05-06 00:08:46 +00005408 while (--envc >= 0)
5409 PyMem_DEL(envlist[envc]);
5410 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005411 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005412 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005413 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 Py_DECREF(opath);
5415 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005416}
5417#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005418#endif /* HAVE_SPAWNV */
5419
5420
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005421#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005422PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005423"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005424Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5425\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005426Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005427
5428static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005429posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005430{
Victor Stinner8c62be82010-05-06 00:08:46 +00005431 pid_t pid;
5432 int result = 0;
5433 _PyImport_AcquireLock();
5434 pid = fork1();
5435 if (pid == 0) {
5436 /* child: this clobbers and resets the import lock. */
5437 PyOS_AfterFork();
5438 } else {
5439 /* parent: release the import lock. */
5440 result = _PyImport_ReleaseLock();
5441 }
5442 if (pid == -1)
5443 return posix_error();
5444 if (result < 0) {
5445 /* Don't clobber the OSError if the fork failed. */
5446 PyErr_SetString(PyExc_RuntimeError,
5447 "not holding the import lock");
5448 return NULL;
5449 }
5450 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005451}
5452#endif
5453
5454
Guido van Rossumad0ee831995-03-01 10:34:45 +00005455#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005456PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005457"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005458Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005459Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005460
Barry Warsaw53699e91996-12-10 23:23:01 +00005461static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005462posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005463{
Victor Stinner8c62be82010-05-06 00:08:46 +00005464 pid_t pid;
5465 int result = 0;
5466 _PyImport_AcquireLock();
5467 pid = fork();
5468 if (pid == 0) {
5469 /* child: this clobbers and resets the import lock. */
5470 PyOS_AfterFork();
5471 } else {
5472 /* parent: release the import lock. */
5473 result = _PyImport_ReleaseLock();
5474 }
5475 if (pid == -1)
5476 return posix_error();
5477 if (result < 0) {
5478 /* Don't clobber the OSError if the fork failed. */
5479 PyErr_SetString(PyExc_RuntimeError,
5480 "not holding the import lock");
5481 return NULL;
5482 }
5483 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005484}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005485#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005486
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005487#ifdef HAVE_SCHED_H
5488
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005489#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5490
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005491PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5492"sched_get_priority_max(policy)\n\n\
5493Get the maximum scheduling priority for *policy*.");
5494
5495static PyObject *
5496posix_sched_get_priority_max(PyObject *self, PyObject *args)
5497{
5498 int policy, max;
5499
5500 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5501 return NULL;
5502 max = sched_get_priority_max(policy);
5503 if (max < 0)
5504 return posix_error();
5505 return PyLong_FromLong(max);
5506}
5507
5508PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5509"sched_get_priority_min(policy)\n\n\
5510Get the minimum scheduling priority for *policy*.");
5511
5512static PyObject *
5513posix_sched_get_priority_min(PyObject *self, PyObject *args)
5514{
5515 int policy, min;
5516
5517 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5518 return NULL;
5519 min = sched_get_priority_min(policy);
5520 if (min < 0)
5521 return posix_error();
5522 return PyLong_FromLong(min);
5523}
5524
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005525#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5526
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005527#ifdef HAVE_SCHED_SETSCHEDULER
5528
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005529PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5530"sched_getscheduler(pid)\n\n\
5531Get the scheduling policy for the process with a PID of *pid*.\n\
5532Passing a PID of 0 returns the scheduling policy for the calling process.");
5533
5534static PyObject *
5535posix_sched_getscheduler(PyObject *self, PyObject *args)
5536{
5537 pid_t pid;
5538 int policy;
5539
5540 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5541 return NULL;
5542 policy = sched_getscheduler(pid);
5543 if (policy < 0)
5544 return posix_error();
5545 return PyLong_FromLong(policy);
5546}
5547
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005548#endif
5549
5550#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5551
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005552static PyObject *
5553sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5554{
5555 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005556 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005557
5558 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5559 return NULL;
5560 res = PyStructSequence_New(type);
5561 if (!res)
5562 return NULL;
5563 Py_INCREF(priority);
5564 PyStructSequence_SET_ITEM(res, 0, priority);
5565 return res;
5566}
5567
5568PyDoc_STRVAR(sched_param__doc__,
5569"sched_param(sched_priority): A scheduling parameter.\n\n\
5570Current has only one field: sched_priority");
5571
5572static PyStructSequence_Field sched_param_fields[] = {
5573 {"sched_priority", "the scheduling priority"},
5574 {0}
5575};
5576
5577static PyStructSequence_Desc sched_param_desc = {
5578 "sched_param", /* name */
5579 sched_param__doc__, /* doc */
5580 sched_param_fields,
5581 1
5582};
5583
5584static int
5585convert_sched_param(PyObject *param, struct sched_param *res)
5586{
5587 long priority;
5588
5589 if (Py_TYPE(param) != &SchedParamType) {
5590 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5591 return 0;
5592 }
5593 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5594 if (priority == -1 && PyErr_Occurred())
5595 return 0;
5596 if (priority > INT_MAX || priority < INT_MIN) {
5597 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5598 return 0;
5599 }
5600 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5601 return 1;
5602}
5603
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005604#endif
5605
5606#ifdef HAVE_SCHED_SETSCHEDULER
5607
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005608PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5609"sched_setscheduler(pid, policy, param)\n\n\
5610Set the scheduling policy, *policy*, for *pid*.\n\
5611If *pid* is 0, the calling process is changed.\n\
5612*param* is an instance of sched_param.");
5613
5614static PyObject *
5615posix_sched_setscheduler(PyObject *self, PyObject *args)
5616{
5617 pid_t pid;
5618 int policy;
5619 struct sched_param param;
5620
5621 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5622 &pid, &policy, &convert_sched_param, &param))
5623 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005624
5625 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005626 ** sched_setscheduler() returns 0 in Linux, but the previous
5627 ** scheduling policy under Solaris/Illumos, and others.
5628 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005629 */
5630 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005631 return posix_error();
5632 Py_RETURN_NONE;
5633}
5634
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005635#endif
5636
5637#ifdef HAVE_SCHED_SETPARAM
5638
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005639PyDoc_STRVAR(posix_sched_getparam__doc__,
5640"sched_getparam(pid) -> sched_param\n\n\
5641Returns scheduling parameters for the process with *pid* as an instance of the\n\
5642sched_param class. A PID of 0 means the calling process.");
5643
5644static PyObject *
5645posix_sched_getparam(PyObject *self, PyObject *args)
5646{
5647 pid_t pid;
5648 struct sched_param param;
5649 PyObject *res, *priority;
5650
5651 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5652 return NULL;
5653 if (sched_getparam(pid, &param))
5654 return posix_error();
5655 res = PyStructSequence_New(&SchedParamType);
5656 if (!res)
5657 return NULL;
5658 priority = PyLong_FromLong(param.sched_priority);
5659 if (!priority) {
5660 Py_DECREF(res);
5661 return NULL;
5662 }
5663 PyStructSequence_SET_ITEM(res, 0, priority);
5664 return res;
5665}
5666
5667PyDoc_STRVAR(posix_sched_setparam__doc__,
5668"sched_setparam(pid, param)\n\n\
5669Set scheduling parameters for a process with PID *pid*.\n\
5670A PID of 0 means the calling process.");
5671
5672static PyObject *
5673posix_sched_setparam(PyObject *self, PyObject *args)
5674{
5675 pid_t pid;
5676 struct sched_param param;
5677
5678 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5679 &pid, &convert_sched_param, &param))
5680 return NULL;
5681 if (sched_setparam(pid, &param))
5682 return posix_error();
5683 Py_RETURN_NONE;
5684}
5685
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005686#endif
5687
5688#ifdef HAVE_SCHED_RR_GET_INTERVAL
5689
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005690PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5691"sched_rr_get_interval(pid) -> float\n\n\
5692Return the round-robin quantum for the process with PID *pid* in seconds.");
5693
5694static PyObject *
5695posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5696{
5697 pid_t pid;
5698 struct timespec interval;
5699
5700 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5701 return NULL;
5702 if (sched_rr_get_interval(pid, &interval))
5703 return posix_error();
5704 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5705}
5706
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005707#endif
5708
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005709PyDoc_STRVAR(posix_sched_yield__doc__,
5710"sched_yield()\n\n\
5711Voluntarily relinquish the CPU.");
5712
5713static PyObject *
5714posix_sched_yield(PyObject *self, PyObject *noargs)
5715{
5716 if (sched_yield())
5717 return posix_error();
5718 Py_RETURN_NONE;
5719}
5720
Benjamin Peterson2740af82011-08-02 17:41:34 -05005721#ifdef HAVE_SCHED_SETAFFINITY
5722
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005723typedef struct {
5724 PyObject_HEAD;
5725 Py_ssize_t size;
5726 int ncpus;
5727 cpu_set_t *set;
5728} Py_cpu_set;
5729
5730static PyTypeObject cpu_set_type;
5731
5732static void
5733cpu_set_dealloc(Py_cpu_set *set)
5734{
5735 assert(set->set);
5736 CPU_FREE(set->set);
5737 Py_TYPE(set)->tp_free(set);
5738}
5739
5740static Py_cpu_set *
5741make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
5742{
5743 Py_cpu_set *set;
5744
5745 if (size < 0) {
5746 PyErr_SetString(PyExc_ValueError, "negative size");
5747 return NULL;
5748 }
5749 set = (Py_cpu_set *)type->tp_alloc(type, 0);
5750 if (!set)
5751 return NULL;
5752 set->ncpus = size;
5753 set->size = CPU_ALLOC_SIZE(size);
5754 set->set = CPU_ALLOC(size);
5755 if (!set->set) {
5756 type->tp_free(set);
5757 PyErr_NoMemory();
5758 return NULL;
5759 }
5760 CPU_ZERO_S(set->size, set->set);
5761 return set;
5762}
5763
5764static PyObject *
5765cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5766{
5767 int size;
5768
5769 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5770 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5771 return NULL;
5772 return (PyObject *)make_new_cpu_set(type, size);
5773}
5774
Jesus Cea53231732012-08-03 14:18:11 +02005775PyDoc_STRVAR(cpu_set_sizeof_doc,
5776"cpu_set.__sizeof__() -> int\n\n\
5777Returns size in memory, in bytes.");
5778
5779static PyObject *
5780cpu_set_sizeof(Py_cpu_set *set, PyObject *noargs)
5781{
5782 Py_ssize_t res = 0;
5783
5784 res = sizeof(Py_cpu_set);
5785 res += set->size;
5786 return PyLong_FromSsize_t(res);
5787}
5788
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005789static PyObject *
5790cpu_set_repr(Py_cpu_set *set)
5791{
5792 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005793}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005794
5795static Py_ssize_t
5796cpu_set_len(Py_cpu_set *set)
5797{
5798 return set->ncpus;
5799}
5800
5801static int
5802_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5803{
5804 int cpu;
5805 if (!PyArg_ParseTuple(args, requester, &cpu))
5806 return -1;
5807 if (cpu < 0) {
5808 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5809 return -1;
5810 }
5811 if (cpu >= set->ncpus) {
5812 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5813 return -1;
5814 }
5815 return cpu;
5816}
5817
5818PyDoc_STRVAR(cpu_set_set_doc,
5819"cpu_set.set(i)\n\n\
5820Add CPU *i* to the set.");
5821
5822static PyObject *
5823cpu_set_set(Py_cpu_set *set, PyObject *args)
5824{
5825 int cpu = _get_cpu(set, "i|set", args);
5826 if (cpu == -1)
5827 return NULL;
5828 CPU_SET_S(cpu, set->size, set->set);
5829 Py_RETURN_NONE;
5830}
5831
5832PyDoc_STRVAR(cpu_set_count_doc,
5833"cpu_set.count() -> int\n\n\
5834Return the number of CPUs active in the set.");
5835
5836static PyObject *
5837cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5838{
5839 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5840}
5841
5842PyDoc_STRVAR(cpu_set_clear_doc,
5843"cpu_set.clear(i)\n\n\
5844Remove CPU *i* from the set.");
5845
5846static PyObject *
5847cpu_set_clear(Py_cpu_set *set, PyObject *args)
5848{
5849 int cpu = _get_cpu(set, "i|clear", args);
5850 if (cpu == -1)
5851 return NULL;
5852 CPU_CLR_S(cpu, set->size, set->set);
5853 Py_RETURN_NONE;
5854}
5855
5856PyDoc_STRVAR(cpu_set_isset_doc,
5857"cpu_set.isset(i) -> bool\n\n\
5858Test if CPU *i* is in the set.");
5859
5860static PyObject *
5861cpu_set_isset(Py_cpu_set *set, PyObject *args)
5862{
5863 int cpu = _get_cpu(set, "i|isset", args);
5864 if (cpu == -1)
5865 return NULL;
5866 if (CPU_ISSET_S(cpu, set->size, set->set))
5867 Py_RETURN_TRUE;
5868 Py_RETURN_FALSE;
5869}
5870
5871PyDoc_STRVAR(cpu_set_zero_doc,
5872"cpu_set.zero()\n\n\
5873Clear the cpu_set.");
5874
5875static PyObject *
5876cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5877{
5878 CPU_ZERO_S(set->size, set->set);
5879 Py_RETURN_NONE;
5880}
5881
5882static PyObject *
5883cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5884{
5885 int eq;
5886
Brian Curtindfc80e32011-08-10 20:28:54 -05005887 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5888 Py_RETURN_NOTIMPLEMENTED;
5889
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005890 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5891 if ((op == Py_EQ) ? eq : !eq)
5892 Py_RETURN_TRUE;
5893 else
5894 Py_RETURN_FALSE;
5895}
5896
5897#define CPU_SET_BINOP(name, op) \
5898 static PyObject * \
5899 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5900 if (res) { \
5901 Py_INCREF(res); \
5902 } \
5903 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005904 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005905 if (!res) \
5906 return NULL; \
5907 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005908 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005909 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005910 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005911 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005912 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005913 op(res->size, res->set, left->set, right->set); \
5914 return (PyObject *)res; \
5915 } \
5916 static PyObject * \
5917 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5918 return do_cpu_set_##name(left, right, NULL); \
5919 } \
5920 static PyObject * \
5921 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5922 return do_cpu_set_##name(left, right, left); \
5923 } \
5924
5925CPU_SET_BINOP(and, CPU_AND_S)
5926CPU_SET_BINOP(or, CPU_OR_S)
5927CPU_SET_BINOP(xor, CPU_XOR_S)
5928#undef CPU_SET_BINOP
5929
5930PyDoc_STRVAR(cpu_set_doc,
5931"cpu_set(size)\n\n\
5932Create an empty mask of CPUs.");
5933
5934static PyNumberMethods cpu_set_as_number = {
5935 0, /*nb_add*/
5936 0, /*nb_subtract*/
5937 0, /*nb_multiply*/
5938 0, /*nb_remainder*/
5939 0, /*nb_divmod*/
5940 0, /*nb_power*/
5941 0, /*nb_negative*/
5942 0, /*nb_positive*/
5943 0, /*nb_absolute*/
5944 0, /*nb_bool*/
5945 0, /*nb_invert*/
5946 0, /*nb_lshift*/
5947 0, /*nb_rshift*/
5948 (binaryfunc)cpu_set_and, /*nb_and*/
5949 (binaryfunc)cpu_set_xor, /*nb_xor*/
5950 (binaryfunc)cpu_set_or, /*nb_or*/
5951 0, /*nb_int*/
5952 0, /*nb_reserved*/
5953 0, /*nb_float*/
5954 0, /*nb_inplace_add*/
5955 0, /*nb_inplace_subtract*/
5956 0, /*nb_inplace_multiply*/
5957 0, /*nb_inplace_remainder*/
5958 0, /*nb_inplace_power*/
5959 0, /*nb_inplace_lshift*/
5960 0, /*nb_inplace_rshift*/
5961 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5962 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5963 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5964};
5965
5966static PySequenceMethods cpu_set_as_sequence = {
5967 (lenfunc)cpu_set_len, /* sq_length */
5968};
5969
5970static PyMethodDef cpu_set_methods[] = {
5971 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5972 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5973 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5974 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5975 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
Jesus Cea53231732012-08-03 14:18:11 +02005976 {"__sizeof__", (PyCFunction)cpu_set_sizeof, METH_NOARGS, cpu_set_sizeof_doc},
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005977 {NULL, NULL} /* sentinel */
5978};
5979
5980static PyTypeObject cpu_set_type = {
5981 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5982 "posix.cpu_set", /* tp_name */
5983 sizeof(Py_cpu_set), /* tp_basicsize */
5984 0, /* tp_itemsize */
5985 /* methods */
5986 (destructor)cpu_set_dealloc, /* tp_dealloc */
5987 0, /* tp_print */
5988 0, /* tp_getattr */
5989 0, /* tp_setattr */
5990 0, /* tp_reserved */
5991 (reprfunc)cpu_set_repr, /* tp_repr */
5992 &cpu_set_as_number, /* tp_as_number */
5993 &cpu_set_as_sequence, /* tp_as_sequence */
5994 0, /* tp_as_mapping */
5995 PyObject_HashNotImplemented, /* tp_hash */
5996 0, /* tp_call */
5997 0, /* tp_str */
5998 PyObject_GenericGetAttr, /* tp_getattro */
5999 0, /* tp_setattro */
6000 0, /* tp_as_buffer */
6001 Py_TPFLAGS_DEFAULT, /* tp_flags */
6002 cpu_set_doc, /* tp_doc */
6003 0, /* tp_traverse */
6004 0, /* tp_clear */
6005 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
6006 0, /* tp_weaklistoffset */
6007 0, /* tp_iter */
6008 0, /* tp_iternext */
6009 cpu_set_methods, /* tp_methods */
6010 0, /* tp_members */
6011 0, /* tp_getset */
6012 0, /* tp_base */
6013 0, /* tp_dict */
6014 0, /* tp_descr_get */
6015 0, /* tp_descr_set */
6016 0, /* tp_dictoffset */
6017 0, /* tp_init */
6018 PyType_GenericAlloc, /* tp_alloc */
6019 cpu_set_new, /* tp_new */
6020 PyObject_Del, /* tp_free */
6021};
6022
6023PyDoc_STRVAR(posix_sched_setaffinity__doc__,
6024"sched_setaffinity(pid, cpu_set)\n\n\
6025Set the affinity of the process with PID *pid* to *cpu_set*.");
6026
6027static PyObject *
6028posix_sched_setaffinity(PyObject *self, PyObject *args)
6029{
6030 pid_t pid;
6031 Py_cpu_set *cpu_set;
6032
Benjamin Petersona17a5d62011-08-09 16:49:13 -05006033 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006034 &pid, &cpu_set_type, &cpu_set))
6035 return NULL;
6036 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
6037 return posix_error();
6038 Py_RETURN_NONE;
6039}
6040
6041PyDoc_STRVAR(posix_sched_getaffinity__doc__,
6042"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
6043Return the affinity of the process with PID *pid*.\n\
6044The returned cpu_set will be of size *ncpus*.");
6045
6046static PyObject *
6047posix_sched_getaffinity(PyObject *self, PyObject *args)
6048{
6049 pid_t pid;
6050 int ncpus;
6051 Py_cpu_set *res;
6052
Benjamin Peterson7ac92142011-08-03 08:54:26 -05006053 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006054 &pid, &ncpus))
6055 return NULL;
6056 res = make_new_cpu_set(&cpu_set_type, ncpus);
6057 if (!res)
6058 return NULL;
6059 if (sched_getaffinity(pid, res->size, res->set)) {
6060 Py_DECREF(res);
6061 return posix_error();
6062 }
6063 return (PyObject *)res;
6064}
6065
Benjamin Peterson2740af82011-08-02 17:41:34 -05006066#endif /* HAVE_SCHED_SETAFFINITY */
6067
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006068#endif /* HAVE_SCHED_H */
6069
Neal Norwitzb59798b2003-03-21 01:43:31 +00006070/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006071/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6072#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006073#define DEV_PTY_FILE "/dev/ptc"
6074#define HAVE_DEV_PTMX
6075#else
6076#define DEV_PTY_FILE "/dev/ptmx"
6077#endif
6078
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006079#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006080#ifdef HAVE_PTY_H
6081#include <pty.h>
6082#else
6083#ifdef HAVE_LIBUTIL_H
6084#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006085#else
6086#ifdef HAVE_UTIL_H
6087#include <util.h>
6088#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006089#endif /* HAVE_LIBUTIL_H */
6090#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006091#ifdef HAVE_STROPTS_H
6092#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006093#endif
6094#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006095
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006096#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006098"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006100
6101static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006102posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006103{
Victor Stinner8c62be82010-05-06 00:08:46 +00006104 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006105#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006107#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006108#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006110#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006112#endif
6113#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006114
Thomas Wouters70c21a12000-07-14 14:28:33 +00006115#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006116 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6117 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006118#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006119 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6120 if (slave_name == NULL)
6121 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006122
Victor Stinner8c62be82010-05-06 00:08:46 +00006123 slave_fd = open(slave_name, O_RDWR);
6124 if (slave_fd < 0)
6125 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006126#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006127 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6128 if (master_fd < 0)
6129 return posix_error();
6130 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6131 /* change permission of slave */
6132 if (grantpt(master_fd) < 0) {
6133 PyOS_setsig(SIGCHLD, sig_saved);
6134 return posix_error();
6135 }
6136 /* unlock slave */
6137 if (unlockpt(master_fd) < 0) {
6138 PyOS_setsig(SIGCHLD, sig_saved);
6139 return posix_error();
6140 }
6141 PyOS_setsig(SIGCHLD, sig_saved);
6142 slave_name = ptsname(master_fd); /* get name of slave */
6143 if (slave_name == NULL)
6144 return posix_error();
6145 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6146 if (slave_fd < 0)
6147 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006148#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6150 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006151#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006152 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006153#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006154#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006155#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006156
Victor Stinner8c62be82010-05-06 00:08:46 +00006157 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006158
Fred Drake8cef4cf2000-06-28 16:40:38 +00006159}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006160#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006161
6162#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006164"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006165Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6166Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006167To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006168
6169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006170posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006171{
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 int master_fd = -1, result = 0;
6173 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006174
Victor Stinner8c62be82010-05-06 00:08:46 +00006175 _PyImport_AcquireLock();
6176 pid = forkpty(&master_fd, NULL, NULL, NULL);
6177 if (pid == 0) {
6178 /* child: this clobbers and resets the import lock. */
6179 PyOS_AfterFork();
6180 } else {
6181 /* parent: release the import lock. */
6182 result = _PyImport_ReleaseLock();
6183 }
6184 if (pid == -1)
6185 return posix_error();
6186 if (result < 0) {
6187 /* Don't clobber the OSError if the fork failed. */
6188 PyErr_SetString(PyExc_RuntimeError,
6189 "not holding the import lock");
6190 return NULL;
6191 }
6192 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006193}
6194#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006195
Ross Lagerwall7807c352011-03-17 20:20:30 +02006196
Guido van Rossumad0ee831995-03-01 10:34:45 +00006197#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006199"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006201
Barry Warsaw53699e91996-12-10 23:23:01 +00006202static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006203posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006204{
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006206}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006207#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006208
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006209
Guido van Rossumad0ee831995-03-01 10:34:45 +00006210#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006211PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006212"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006214
Barry Warsaw53699e91996-12-10 23:23:01 +00006215static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006216posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006217{
Victor Stinner8c62be82010-05-06 00:08:46 +00006218 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006219}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006220#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006222
Guido van Rossumad0ee831995-03-01 10:34:45 +00006223#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006224PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006225"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006226Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006227
Barry Warsaw53699e91996-12-10 23:23:01 +00006228static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006229posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006230{
Victor Stinner8c62be82010-05-06 00:08:46 +00006231 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006232}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006233#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006234
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006235
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006236PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006237"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006238Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006239
Barry Warsaw53699e91996-12-10 23:23:01 +00006240static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006241posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006242{
Victor Stinner8c62be82010-05-06 00:08:46 +00006243 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006244}
6245
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006246#ifdef HAVE_GETGROUPLIST
6247PyDoc_STRVAR(posix_getgrouplist__doc__,
6248"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6249Returns a list of groups to which a user belongs.\n\n\
6250 user: username to lookup\n\
6251 group: base group id of the user");
6252
6253static PyObject *
6254posix_getgrouplist(PyObject *self, PyObject *args)
6255{
6256#ifdef NGROUPS_MAX
6257#define MAX_GROUPS NGROUPS_MAX
6258#else
6259 /* defined to be 16 on Solaris7, so this should be a small number */
6260#define MAX_GROUPS 64
6261#endif
6262
6263 const char *user;
6264 int i, ngroups;
6265 PyObject *list;
6266#ifdef __APPLE__
6267 int *groups, basegid;
6268#else
6269 gid_t *groups, basegid;
6270#endif
6271 ngroups = MAX_GROUPS;
6272
6273 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
6274 return NULL;
6275
6276#ifdef __APPLE__
6277 groups = PyMem_Malloc(ngroups * sizeof(int));
6278#else
6279 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6280#endif
6281 if (groups == NULL)
6282 return PyErr_NoMemory();
6283
6284 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6285 PyMem_Del(groups);
6286 return posix_error();
6287 }
6288
6289 list = PyList_New(ngroups);
6290 if (list == NULL) {
6291 PyMem_Del(groups);
6292 return NULL;
6293 }
6294
6295 for (i = 0; i < ngroups; i++) {
6296 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
6297 if (o == NULL) {
6298 Py_DECREF(list);
6299 PyMem_Del(groups);
6300 return NULL;
6301 }
6302 PyList_SET_ITEM(list, i, o);
6303 }
6304
6305 PyMem_Del(groups);
6306
6307 return list;
6308}
6309#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006310
Fred Drakec9680921999-12-13 16:37:25 +00006311#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006312PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006313"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006315
6316static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006317posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006318{
6319 PyObject *result = NULL;
6320
Fred Drakec9680921999-12-13 16:37:25 +00006321#ifdef NGROUPS_MAX
6322#define MAX_GROUPS NGROUPS_MAX
6323#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006325#define MAX_GROUPS 64
6326#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006327 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006328
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006329 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006330 * This is a helper variable to store the intermediate result when
6331 * that happens.
6332 *
6333 * To keep the code readable the OSX behaviour is unconditional,
6334 * according to the POSIX spec this should be safe on all unix-y
6335 * systems.
6336 */
6337 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006339
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006341 if (n < 0) {
6342 if (errno == EINVAL) {
6343 n = getgroups(0, NULL);
6344 if (n == -1) {
6345 return posix_error();
6346 }
6347 if (n == 0) {
6348 /* Avoid malloc(0) */
6349 alt_grouplist = grouplist;
6350 } else {
6351 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6352 if (alt_grouplist == NULL) {
6353 errno = EINVAL;
6354 return posix_error();
6355 }
6356 n = getgroups(n, alt_grouplist);
6357 if (n == -1) {
6358 PyMem_Free(alt_grouplist);
6359 return posix_error();
6360 }
6361 }
6362 } else {
6363 return posix_error();
6364 }
6365 }
6366 result = PyList_New(n);
6367 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 int i;
6369 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006370 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006372 Py_DECREF(result);
6373 result = NULL;
6374 break;
Fred Drakec9680921999-12-13 16:37:25 +00006375 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006377 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006378 }
6379
6380 if (alt_grouplist != grouplist) {
6381 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006383
Fred Drakec9680921999-12-13 16:37:25 +00006384 return result;
6385}
6386#endif
6387
Antoine Pitroub7572f02009-12-02 20:46:48 +00006388#ifdef HAVE_INITGROUPS
6389PyDoc_STRVAR(posix_initgroups__doc__,
6390"initgroups(username, gid) -> None\n\n\
6391Call the system initgroups() to initialize the group access list with all of\n\
6392the groups of which the specified username is a member, plus the specified\n\
6393group id.");
6394
6395static PyObject *
6396posix_initgroups(PyObject *self, PyObject *args)
6397{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006398 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006400 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006402
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006403 if (!PyArg_ParseTuple(args, "O&l:initgroups",
6404 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006406 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006407
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006408 res = initgroups(username, (gid_t) gid);
6409 Py_DECREF(oname);
6410 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006412
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 Py_INCREF(Py_None);
6414 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006415}
6416#endif
6417
Martin v. Löwis606edc12002-06-13 21:09:11 +00006418#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006419PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006420"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006421Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006422
6423static PyObject *
6424posix_getpgid(PyObject *self, PyObject *args)
6425{
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 pid_t pid, pgid;
6427 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6428 return NULL;
6429 pgid = getpgid(pid);
6430 if (pgid < 0)
6431 return posix_error();
6432 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006433}
6434#endif /* HAVE_GETPGID */
6435
6436
Guido van Rossumb6775db1994-08-01 11:34:53 +00006437#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006438PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006439"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006440Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006441
Barry Warsaw53699e91996-12-10 23:23:01 +00006442static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006443posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006444{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006445#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006447#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006449#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006450}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006451#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006453
Guido van Rossumb6775db1994-08-01 11:34:53 +00006454#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006455PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006456"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006457Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006458
Barry Warsaw53699e91996-12-10 23:23:01 +00006459static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006460posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006461{
Guido van Rossum64933891994-10-20 21:56:42 +00006462#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006463 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006464#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006466#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 return posix_error();
6468 Py_INCREF(Py_None);
6469 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006470}
6471
Guido van Rossumb6775db1994-08-01 11:34:53 +00006472#endif /* HAVE_SETPGRP */
6473
Guido van Rossumad0ee831995-03-01 10:34:45 +00006474#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006475
6476#ifdef MS_WINDOWS
6477#include <tlhelp32.h>
6478
6479static PyObject*
6480win32_getppid()
6481{
6482 HANDLE snapshot;
6483 pid_t mypid;
6484 PyObject* result = NULL;
6485 BOOL have_record;
6486 PROCESSENTRY32 pe;
6487
6488 mypid = getpid(); /* This function never fails */
6489
6490 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6491 if (snapshot == INVALID_HANDLE_VALUE)
6492 return PyErr_SetFromWindowsErr(GetLastError());
6493
6494 pe.dwSize = sizeof(pe);
6495 have_record = Process32First(snapshot, &pe);
6496 while (have_record) {
6497 if (mypid == (pid_t)pe.th32ProcessID) {
6498 /* We could cache the ulong value in a static variable. */
6499 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6500 break;
6501 }
6502
6503 have_record = Process32Next(snapshot, &pe);
6504 }
6505
6506 /* If our loop exits and our pid was not found (result will be NULL)
6507 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6508 * error anyway, so let's raise it. */
6509 if (!result)
6510 result = PyErr_SetFromWindowsErr(GetLastError());
6511
6512 CloseHandle(snapshot);
6513
6514 return result;
6515}
6516#endif /*MS_WINDOWS*/
6517
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006518PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006519"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006520Return the parent's process id. If the parent process has already exited,\n\
6521Windows machines will still return its id; others systems will return the id\n\
6522of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006523
Barry Warsaw53699e91996-12-10 23:23:01 +00006524static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006525posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006526{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006527#ifdef MS_WINDOWS
6528 return win32_getppid();
6529#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006531#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006532}
6533#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006535
Fred Drake12c6e2d1999-12-14 21:25:03 +00006536#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006537PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006538"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006539Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006540
6541static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006542posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006543{
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006545#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006546 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006547 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006548
6549 if (GetUserNameW(user_name, &num_chars)) {
6550 /* num_chars is the number of unicode chars plus null terminator */
6551 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006552 }
6553 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006554 result = PyErr_SetFromWindowsErr(GetLastError());
6555#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 char *name;
6557 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006558
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 errno = 0;
6560 name = getlogin();
6561 if (name == NULL) {
6562 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006563 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006564 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006565 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 }
6567 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006568 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006570#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006571 return result;
6572}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006573#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006574
Guido van Rossumad0ee831995-03-01 10:34:45 +00006575#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006576PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006577"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006578Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006579
Barry Warsaw53699e91996-12-10 23:23:01 +00006580static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006581posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006582{
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006584}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006585#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006587
Guido van Rossumad0ee831995-03-01 10:34:45 +00006588#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006589PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006590"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006591Kill a process with a signal.");
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_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006595{
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 pid_t pid;
6597 int sig;
6598 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6599 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006600#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006601 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6602 APIRET rc;
6603 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006604 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006605
6606 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6607 APIRET rc;
6608 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006609 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006610
6611 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006612 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006613#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 if (kill(pid, sig) == -1)
6615 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006616#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 Py_INCREF(Py_None);
6618 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006619}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006620#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006621
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006622#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006624"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006625Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006626
6627static PyObject *
6628posix_killpg(PyObject *self, PyObject *args)
6629{
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 int sig;
6631 pid_t pgid;
6632 /* XXX some man pages make the `pgid` parameter an int, others
6633 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6634 take the same type. Moreover, pid_t is always at least as wide as
6635 int (else compilation of this module fails), which is safe. */
6636 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6637 return NULL;
6638 if (killpg(pgid, sig) == -1)
6639 return posix_error();
6640 Py_INCREF(Py_None);
6641 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006642}
6643#endif
6644
Brian Curtineb24d742010-04-12 17:16:38 +00006645#ifdef MS_WINDOWS
6646PyDoc_STRVAR(win32_kill__doc__,
6647"kill(pid, sig)\n\n\
6648Kill a process with a signal.");
6649
6650static PyObject *
6651win32_kill(PyObject *self, PyObject *args)
6652{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006653 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 DWORD pid, sig, err;
6655 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006656
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6658 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006659
Victor Stinner8c62be82010-05-06 00:08:46 +00006660 /* Console processes which share a common console can be sent CTRL+C or
6661 CTRL+BREAK events, provided they handle said events. */
6662 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6663 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6664 err = GetLastError();
6665 PyErr_SetFromWindowsErr(err);
6666 }
6667 else
6668 Py_RETURN_NONE;
6669 }
Brian Curtineb24d742010-04-12 17:16:38 +00006670
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6672 attempt to open and terminate the process. */
6673 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6674 if (handle == NULL) {
6675 err = GetLastError();
6676 return PyErr_SetFromWindowsErr(err);
6677 }
Brian Curtineb24d742010-04-12 17:16:38 +00006678
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 if (TerminateProcess(handle, sig) == 0) {
6680 err = GetLastError();
6681 result = PyErr_SetFromWindowsErr(err);
6682 } else {
6683 Py_INCREF(Py_None);
6684 result = Py_None;
6685 }
Brian Curtineb24d742010-04-12 17:16:38 +00006686
Victor Stinner8c62be82010-05-06 00:08:46 +00006687 CloseHandle(handle);
6688 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006689}
6690#endif /* MS_WINDOWS */
6691
Guido van Rossumc0125471996-06-28 18:55:32 +00006692#ifdef HAVE_PLOCK
6693
6694#ifdef HAVE_SYS_LOCK_H
6695#include <sys/lock.h>
6696#endif
6697
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006698PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006699"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006700Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006701
Barry Warsaw53699e91996-12-10 23:23:01 +00006702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006703posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006704{
Victor Stinner8c62be82010-05-06 00:08:46 +00006705 int op;
6706 if (!PyArg_ParseTuple(args, "i:plock", &op))
6707 return NULL;
6708 if (plock(op) == -1)
6709 return posix_error();
6710 Py_INCREF(Py_None);
6711 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006712}
6713#endif
6714
Guido van Rossumb6775db1994-08-01 11:34:53 +00006715#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006716PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006717"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006718Set the current process's user id.");
6719
Barry Warsaw53699e91996-12-10 23:23:01 +00006720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006721posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006722{
Victor Stinner8c62be82010-05-06 00:08:46 +00006723 long uid_arg;
6724 uid_t uid;
6725 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
6726 return NULL;
6727 uid = uid_arg;
6728 if (uid != uid_arg) {
6729 PyErr_SetString(PyExc_OverflowError, "user id too big");
6730 return NULL;
6731 }
6732 if (setuid(uid) < 0)
6733 return posix_error();
6734 Py_INCREF(Py_None);
6735 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006736}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006737#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006738
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006739
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006740#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006741PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006742"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006743Set the current process's effective user id.");
6744
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006745static PyObject *
6746posix_seteuid (PyObject *self, PyObject *args)
6747{
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 long euid_arg;
6749 uid_t euid;
6750 if (!PyArg_ParseTuple(args, "l", &euid_arg))
6751 return NULL;
6752 euid = euid_arg;
6753 if (euid != euid_arg) {
6754 PyErr_SetString(PyExc_OverflowError, "user id too big");
6755 return NULL;
6756 }
6757 if (seteuid(euid) < 0) {
6758 return posix_error();
6759 } else {
6760 Py_INCREF(Py_None);
6761 return Py_None;
6762 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006763}
6764#endif /* HAVE_SETEUID */
6765
6766#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006767PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006768"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006769Set the current process's effective group id.");
6770
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006771static PyObject *
6772posix_setegid (PyObject *self, PyObject *args)
6773{
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 long egid_arg;
6775 gid_t egid;
6776 if (!PyArg_ParseTuple(args, "l", &egid_arg))
6777 return NULL;
6778 egid = egid_arg;
6779 if (egid != egid_arg) {
6780 PyErr_SetString(PyExc_OverflowError, "group id too big");
6781 return NULL;
6782 }
6783 if (setegid(egid) < 0) {
6784 return posix_error();
6785 } else {
6786 Py_INCREF(Py_None);
6787 return Py_None;
6788 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006789}
6790#endif /* HAVE_SETEGID */
6791
6792#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006793PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006794"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006795Set the current process's real and effective user ids.");
6796
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006797static PyObject *
6798posix_setreuid (PyObject *self, PyObject *args)
6799{
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 long ruid_arg, euid_arg;
6801 uid_t ruid, euid;
6802 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6803 return NULL;
6804 if (ruid_arg == -1)
6805 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6806 else
6807 ruid = ruid_arg; /* otherwise, assign from our long */
6808 if (euid_arg == -1)
6809 euid = (uid_t)-1;
6810 else
6811 euid = euid_arg;
6812 if ((euid_arg != -1 && euid != euid_arg) ||
6813 (ruid_arg != -1 && ruid != ruid_arg)) {
6814 PyErr_SetString(PyExc_OverflowError, "user id too big");
6815 return NULL;
6816 }
6817 if (setreuid(ruid, euid) < 0) {
6818 return posix_error();
6819 } else {
6820 Py_INCREF(Py_None);
6821 return Py_None;
6822 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006823}
6824#endif /* HAVE_SETREUID */
6825
6826#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006827PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006828"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006829Set the current process's real and effective group ids.");
6830
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006831static PyObject *
6832posix_setregid (PyObject *self, PyObject *args)
6833{
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 long rgid_arg, egid_arg;
6835 gid_t rgid, egid;
6836 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6837 return NULL;
6838 if (rgid_arg == -1)
6839 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6840 else
6841 rgid = rgid_arg; /* otherwise, assign from our long */
6842 if (egid_arg == -1)
6843 egid = (gid_t)-1;
6844 else
6845 egid = egid_arg;
6846 if ((egid_arg != -1 && egid != egid_arg) ||
6847 (rgid_arg != -1 && rgid != rgid_arg)) {
6848 PyErr_SetString(PyExc_OverflowError, "group id too big");
6849 return NULL;
6850 }
6851 if (setregid(rgid, egid) < 0) {
6852 return posix_error();
6853 } else {
6854 Py_INCREF(Py_None);
6855 return Py_None;
6856 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006857}
6858#endif /* HAVE_SETREGID */
6859
Guido van Rossumb6775db1994-08-01 11:34:53 +00006860#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006861PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006862"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006863Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006864
Barry Warsaw53699e91996-12-10 23:23:01 +00006865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006866posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006867{
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 long gid_arg;
6869 gid_t gid;
6870 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6871 return NULL;
6872 gid = gid_arg;
6873 if (gid != gid_arg) {
6874 PyErr_SetString(PyExc_OverflowError, "group id too big");
6875 return NULL;
6876 }
6877 if (setgid(gid) < 0)
6878 return posix_error();
6879 Py_INCREF(Py_None);
6880 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006881}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006882#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006883
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006884#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006885PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006886"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006887Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006888
6889static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006890posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006891{
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 int i, len;
6893 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006894
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 if (!PySequence_Check(groups)) {
6896 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6897 return NULL;
6898 }
6899 len = PySequence_Size(groups);
6900 if (len > MAX_GROUPS) {
6901 PyErr_SetString(PyExc_ValueError, "too many groups");
6902 return NULL;
6903 }
6904 for(i = 0; i < len; i++) {
6905 PyObject *elem;
6906 elem = PySequence_GetItem(groups, i);
6907 if (!elem)
6908 return NULL;
6909 if (!PyLong_Check(elem)) {
6910 PyErr_SetString(PyExc_TypeError,
6911 "groups must be integers");
6912 Py_DECREF(elem);
6913 return NULL;
6914 } else {
6915 unsigned long x = PyLong_AsUnsignedLong(elem);
6916 if (PyErr_Occurred()) {
6917 PyErr_SetString(PyExc_TypeError,
6918 "group id too big");
6919 Py_DECREF(elem);
6920 return NULL;
6921 }
6922 grouplist[i] = x;
6923 /* read back the value to see if it fitted in gid_t */
6924 if (grouplist[i] != x) {
6925 PyErr_SetString(PyExc_TypeError,
6926 "group id too big");
6927 Py_DECREF(elem);
6928 return NULL;
6929 }
6930 }
6931 Py_DECREF(elem);
6932 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006933
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 if (setgroups(len, grouplist) < 0)
6935 return posix_error();
6936 Py_INCREF(Py_None);
6937 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006938}
6939#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006940
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6942static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006943wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006944{
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 PyObject *result;
6946 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006947 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006948
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 if (pid == -1)
6950 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006951
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 if (struct_rusage == NULL) {
6953 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6954 if (m == NULL)
6955 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006956 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006957 Py_DECREF(m);
6958 if (struct_rusage == NULL)
6959 return NULL;
6960 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006961
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6963 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6964 if (!result)
6965 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006966
6967#ifndef doubletime
6968#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6969#endif
6970
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006972 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006974 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006975#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6977 SET_INT(result, 2, ru->ru_maxrss);
6978 SET_INT(result, 3, ru->ru_ixrss);
6979 SET_INT(result, 4, ru->ru_idrss);
6980 SET_INT(result, 5, ru->ru_isrss);
6981 SET_INT(result, 6, ru->ru_minflt);
6982 SET_INT(result, 7, ru->ru_majflt);
6983 SET_INT(result, 8, ru->ru_nswap);
6984 SET_INT(result, 9, ru->ru_inblock);
6985 SET_INT(result, 10, ru->ru_oublock);
6986 SET_INT(result, 11, ru->ru_msgsnd);
6987 SET_INT(result, 12, ru->ru_msgrcv);
6988 SET_INT(result, 13, ru->ru_nsignals);
6989 SET_INT(result, 14, ru->ru_nvcsw);
6990 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006991#undef SET_INT
6992
Victor Stinner8c62be82010-05-06 00:08:46 +00006993 if (PyErr_Occurred()) {
6994 Py_DECREF(result);
6995 return NULL;
6996 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006997
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006999}
7000#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
7001
7002#ifdef HAVE_WAIT3
7003PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007004"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007005Wait for completion of a child process.");
7006
7007static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007008posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007009{
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 pid_t pid;
7011 int options;
7012 struct rusage ru;
7013 WAIT_TYPE status;
7014 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007015
Victor Stinner4195b5c2012-02-08 23:03:19 +01007016 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007017 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007018
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 Py_BEGIN_ALLOW_THREADS
7020 pid = wait3(&status, options, &ru);
7021 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007022
Victor Stinner4195b5c2012-02-08 23:03:19 +01007023 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007024}
7025#endif /* HAVE_WAIT3 */
7026
7027#ifdef HAVE_WAIT4
7028PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007029"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007030Wait for completion of a given child process.");
7031
7032static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007033posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007034{
Victor Stinner8c62be82010-05-06 00:08:46 +00007035 pid_t pid;
7036 int options;
7037 struct rusage ru;
7038 WAIT_TYPE status;
7039 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007040
Victor Stinner4195b5c2012-02-08 23:03:19 +01007041 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007043
Victor Stinner8c62be82010-05-06 00:08:46 +00007044 Py_BEGIN_ALLOW_THREADS
7045 pid = wait4(pid, &status, options, &ru);
7046 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007047
Victor Stinner4195b5c2012-02-08 23:03:19 +01007048 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007049}
7050#endif /* HAVE_WAIT4 */
7051
Ross Lagerwall7807c352011-03-17 20:20:30 +02007052#if defined(HAVE_WAITID) && !defined(__APPLE__)
7053PyDoc_STRVAR(posix_waitid__doc__,
7054"waitid(idtype, id, options) -> waitid_result\n\n\
7055Wait for the completion of one or more child processes.\n\n\
7056idtype can be P_PID, P_PGID or P_ALL.\n\
7057id specifies the pid to wait on.\n\
7058options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
7059or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
7060Returns either waitid_result or None if WNOHANG is specified and there are\n\
7061no children in a waitable state.");
7062
7063static PyObject *
7064posix_waitid(PyObject *self, PyObject *args)
7065{
7066 PyObject *result;
7067 idtype_t idtype;
7068 id_t id;
7069 int options, res;
7070 siginfo_t si;
7071 si.si_pid = 0;
7072 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7073 return NULL;
7074 Py_BEGIN_ALLOW_THREADS
7075 res = waitid(idtype, id, &si, options);
7076 Py_END_ALLOW_THREADS
7077 if (res == -1)
7078 return posix_error();
7079
7080 if (si.si_pid == 0)
7081 Py_RETURN_NONE;
7082
7083 result = PyStructSequence_New(&WaitidResultType);
7084 if (!result)
7085 return NULL;
7086
7087 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
7088 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
7089 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7090 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7091 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7092 if (PyErr_Occurred()) {
7093 Py_DECREF(result);
7094 return NULL;
7095 }
7096
7097 return result;
7098}
7099#endif
7100
Guido van Rossumb6775db1994-08-01 11:34:53 +00007101#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007102PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007103"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007104Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007105
Barry Warsaw53699e91996-12-10 23:23:01 +00007106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007107posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007108{
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 pid_t pid;
7110 int options;
7111 WAIT_TYPE status;
7112 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007113
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7115 return NULL;
7116 Py_BEGIN_ALLOW_THREADS
7117 pid = waitpid(pid, &status, options);
7118 Py_END_ALLOW_THREADS
7119 if (pid == -1)
7120 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007121
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007123}
7124
Tim Petersab034fa2002-02-01 11:27:43 +00007125#elif defined(HAVE_CWAIT)
7126
7127/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007128PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007129"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007130"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007131
7132static PyObject *
7133posix_waitpid(PyObject *self, PyObject *args)
7134{
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 Py_intptr_t pid;
7136 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007137
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7139 return NULL;
7140 Py_BEGIN_ALLOW_THREADS
7141 pid = _cwait(&status, pid, options);
7142 Py_END_ALLOW_THREADS
7143 if (pid == -1)
7144 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007145
Victor Stinner8c62be82010-05-06 00:08:46 +00007146 /* shift the status left a byte so this is more like the POSIX waitpid */
7147 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007148}
7149#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007150
Guido van Rossumad0ee831995-03-01 10:34:45 +00007151#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007152PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007153"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007154Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007155
Barry Warsaw53699e91996-12-10 23:23:01 +00007156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007157posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007158{
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 pid_t pid;
7160 WAIT_TYPE status;
7161 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007162
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 Py_BEGIN_ALLOW_THREADS
7164 pid = wait(&status);
7165 Py_END_ALLOW_THREADS
7166 if (pid == -1)
7167 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007168
Victor Stinner8c62be82010-05-06 00:08:46 +00007169 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007170}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007171#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007172
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007173
Larry Hastings9cf065c2012-06-22 16:30:09 -07007174#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7175PyDoc_STRVAR(readlink__doc__,
7176"readlink(path, *, dir_fd=None) -> path\n\n\
7177Return a string representing the path to which the symbolic link points.\n\
7178\n\
7179If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7180 and path should be relative; path will then be relative to that directory.\n\
7181dir_fd may not be implemented on your platform.\n\
7182 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007183#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007184
Guido van Rossumb6775db1994-08-01 11:34:53 +00007185#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007186
Barry Warsaw53699e91996-12-10 23:23:01 +00007187static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007188posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007189{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190 path_t path;
7191 int dir_fd = DEFAULT_DIR_FD;
7192 char buffer[MAXPATHLEN];
7193 ssize_t length;
7194 PyObject *return_value = NULL;
7195 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007196
Larry Hastings9cf065c2012-06-22 16:30:09 -07007197 memset(&path, 0, sizeof(path));
7198 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7199 path_converter, &path,
7200#ifdef HAVE_READLINKAT
7201 dir_fd_converter, &dir_fd
7202#else
7203 dir_fd_unavailable, &dir_fd
7204#endif
7205 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007206 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007207
Victor Stinner8c62be82010-05-06 00:08:46 +00007208 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007209#ifdef HAVE_READLINKAT
7210 if (dir_fd != DEFAULT_DIR_FD)
7211 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007212 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007213#endif
7214 length = readlink(path.narrow, buffer, sizeof(buffer));
7215 Py_END_ALLOW_THREADS
7216
7217 if (length < 0) {
7218 return_value = path_posix_error("readlink", &path);
7219 goto exit;
7220 }
7221
7222 if (PyUnicode_Check(path.object))
7223 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7224 else
7225 return_value = PyBytes_FromStringAndSize(buffer, length);
7226exit:
7227 path_cleanup(&path);
7228 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007229}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007230
7231
Guido van Rossumb6775db1994-08-01 11:34:53 +00007232#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007234
Larry Hastings9cf065c2012-06-22 16:30:09 -07007235#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007236PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007237"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7238Create a symbolic link pointing to src named dst.\n\n\
7239target_is_directory is required on Windows if the target is to be\n\
7240 interpreted as a directory. (On Windows, symlink requires\n\
7241 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7242 target_is_directory is ignored on non-Windows platforms.\n\
7243\n\
7244If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7245 and path should be relative; path will then be relative to that directory.\n\
7246dir_fd may not be implemented on your platform.\n\
7247 If it is unavailable, using it will raise a NotImplementedError.");
7248
7249#if defined(MS_WINDOWS)
7250
7251/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7252static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7253static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7254static int
7255check_CreateSymbolicLink()
7256{
7257 HINSTANCE hKernel32;
7258 /* only recheck */
7259 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7260 return 1;
7261 hKernel32 = GetModuleHandleW(L"KERNEL32");
7262 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7263 "CreateSymbolicLinkW");
7264 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7265 "CreateSymbolicLinkA");
7266 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7267}
7268
7269#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007270
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007271static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007272posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007273{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007274 path_t src;
7275 path_t dst;
7276 int dir_fd = DEFAULT_DIR_FD;
7277 int target_is_directory = 0;
7278 static char *keywords[] = {"src", "dst", "target_is_directory",
7279 "dir_fd", NULL};
7280 PyObject *return_value;
7281#ifdef MS_WINDOWS
7282 DWORD result;
7283#else
7284 int result;
7285#endif
7286
7287 memset(&src, 0, sizeof(src));
7288 src.argument_name = "src";
7289 memset(&dst, 0, sizeof(dst));
7290 dst.argument_name = "dst";
7291
7292#ifdef MS_WINDOWS
7293 if (!check_CreateSymbolicLink()) {
7294 PyErr_SetString(PyExc_NotImplementedError,
7295 "CreateSymbolicLink functions not found");
7296 return NULL;
7297 }
7298 if (!win32_can_symlink) {
7299 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
7300 return NULL;
7301 }
7302#endif
7303
7304 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7305 keywords,
7306 path_converter, &src,
7307 path_converter, &dst,
7308 &target_is_directory,
7309#ifdef HAVE_SYMLINKAT
7310 dir_fd_converter, &dir_fd
7311#else
7312 dir_fd_unavailable, &dir_fd
7313#endif
7314 ))
7315 return NULL;
7316
7317 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7318 PyErr_SetString(PyExc_ValueError,
7319 "symlink: src and dst must be the same type");
7320 return_value = NULL;
7321 goto exit;
7322 }
7323
7324#ifdef MS_WINDOWS
7325 Py_BEGIN_ALLOW_THREADS
7326 if (dst.wide)
7327 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7328 target_is_directory);
7329 else
7330 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7331 target_is_directory);
7332 Py_END_ALLOW_THREADS
7333
7334 if (!result) {
7335 return_value = win32_error_object("symlink", src.object);
7336 goto exit;
7337 }
7338
7339#else
7340
7341 Py_BEGIN_ALLOW_THREADS
7342#if HAVE_SYMLINKAT
7343 if (dir_fd != DEFAULT_DIR_FD)
7344 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7345 else
7346#endif
7347 result = symlink(src.narrow, dst.narrow);
7348 Py_END_ALLOW_THREADS
7349
7350 if (result) {
7351 return_value = path_error("symlink", &dst);
7352 goto exit;
7353 }
7354#endif
7355
7356 return_value = Py_None;
7357 Py_INCREF(Py_None);
7358 goto exit; /* silence "unused label" warning */
7359exit:
7360 path_cleanup(&src);
7361 path_cleanup(&dst);
7362 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007363}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007364
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007365#endif /* HAVE_SYMLINK */
7366
Larry Hastings9cf065c2012-06-22 16:30:09 -07007367
Brian Curtind40e6f72010-07-08 21:39:08 +00007368#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7369
Brian Curtind40e6f72010-07-08 21:39:08 +00007370static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007371win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007372{
7373 wchar_t *path;
7374 DWORD n_bytes_returned;
7375 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007376 PyObject *po, *result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007377 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007378 HANDLE reparse_point_handle;
7379
7380 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7381 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7382 wchar_t *print_name;
7383
Larry Hastings9cf065c2012-06-22 16:30:09 -07007384 static char *keywords[] = {"path", "dir_fd", NULL};
7385
7386 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7387 &po,
7388 dir_fd_unavailable, &dir_fd
7389 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007390 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007391
Victor Stinnereb5657a2011-09-30 01:44:27 +02007392 path = PyUnicode_AsUnicode(po);
7393 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007394 return NULL;
7395
7396 /* First get a handle to the reparse point */
7397 Py_BEGIN_ALLOW_THREADS
7398 reparse_point_handle = CreateFileW(
7399 path,
7400 0,
7401 0,
7402 0,
7403 OPEN_EXISTING,
7404 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7405 0);
7406 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007407
Brian Curtind40e6f72010-07-08 21:39:08 +00007408 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007409 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007410
Brian Curtind40e6f72010-07-08 21:39:08 +00007411 Py_BEGIN_ALLOW_THREADS
7412 /* New call DeviceIoControl to read the reparse point */
7413 io_result = DeviceIoControl(
7414 reparse_point_handle,
7415 FSCTL_GET_REPARSE_POINT,
7416 0, 0, /* in buffer */
7417 target_buffer, sizeof(target_buffer),
7418 &n_bytes_returned,
7419 0 /* we're not using OVERLAPPED_IO */
7420 );
7421 CloseHandle(reparse_point_handle);
7422 Py_END_ALLOW_THREADS
7423
7424 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007425 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007426
7427 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7428 {
7429 PyErr_SetString(PyExc_ValueError,
7430 "not a symbolic link");
7431 return NULL;
7432 }
Brian Curtin74e45612010-07-09 15:58:59 +00007433 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7434 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7435
7436 result = PyUnicode_FromWideChar(print_name,
7437 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007438 return result;
7439}
7440
7441#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7442
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007443
Larry Hastings605a62d2012-06-24 04:33:36 -07007444static PyStructSequence_Field times_result_fields[] = {
7445 {"user", "user time"},
7446 {"system", "system time"},
7447 {"children_user", "user time of children"},
7448 {"children_system", "system time of children"},
7449 {"elapsed", "elapsed time since an arbitrary point in the past"},
7450 {NULL}
7451};
7452
7453PyDoc_STRVAR(times_result__doc__,
7454"times_result: Result from os.times().\n\n\
7455This object may be accessed either as a tuple of\n\
7456 (user, system, children_user, children_system, elapsed),\n\
7457or via the attributes user, system, children_user, children_system,\n\
7458and elapsed.\n\
7459\n\
7460See os.times for more information.");
7461
7462static PyStructSequence_Desc times_result_desc = {
7463 "times_result", /* name */
7464 times_result__doc__, /* doc */
7465 times_result_fields,
7466 5
7467};
7468
7469static PyTypeObject TimesResultType;
7470
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007471#ifdef MS_WINDOWS
7472#define HAVE_TIMES /* mandatory, for the method table */
7473#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007474
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007475#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007476
7477static PyObject *
7478build_times_result(double user, double system,
7479 double children_user, double children_system,
7480 double elapsed)
7481{
7482 PyObject *value = PyStructSequence_New(&TimesResultType);
7483 if (value == NULL)
7484 return NULL;
7485
7486#define SET(i, field) \
7487 { \
7488 PyObject *o = PyFloat_FromDouble(field); \
7489 if (!o) { \
7490 Py_DECREF(value); \
7491 return NULL; \
7492 } \
7493 PyStructSequence_SET_ITEM(value, i, o); \
7494 } \
7495
7496 SET(0, user);
7497 SET(1, system);
7498 SET(2, children_user);
7499 SET(3, children_system);
7500 SET(4, elapsed);
7501
7502#undef SET
7503
7504 return value;
7505}
7506
7507PyDoc_STRVAR(posix_times__doc__,
7508"times() -> times_result\n\n\
7509Return an object containing floating point numbers indicating process\n\
7510times. The object behaves like a named tuple with these fields:\n\
7511 (utime, stime, cutime, cstime, elapsed_time)");
7512
Guido van Rossumd48f2521997-12-05 22:19:34 +00007513#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7514static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007515system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007516{
7517 ULONG value = 0;
7518
7519 Py_BEGIN_ALLOW_THREADS
7520 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7521 Py_END_ALLOW_THREADS
7522
7523 return value;
7524}
7525
7526static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007527posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007528{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007529 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007530 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 (double)0 /* t.tms_utime / HZ */,
7532 (double)0 /* t.tms_stime / HZ */,
7533 (double)0 /* t.tms_cutime / HZ */,
7534 (double)0 /* t.tms_cstime / HZ */,
7535 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007536}
Larry Hastings605a62d2012-06-24 04:33:36 -07007537#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007538static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007539posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007540{
Victor Stinner8c62be82010-05-06 00:08:46 +00007541 FILETIME create, exit, kernel, user;
7542 HANDLE hProc;
7543 hProc = GetCurrentProcess();
7544 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7545 /* The fields of a FILETIME structure are the hi and lo part
7546 of a 64-bit value expressed in 100 nanosecond units.
7547 1e7 is one second in such units; 1e-7 the inverse.
7548 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7549 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007550 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007551 (double)(user.dwHighDateTime*429.4967296 +
7552 user.dwLowDateTime*1e-7),
7553 (double)(kernel.dwHighDateTime*429.4967296 +
7554 kernel.dwLowDateTime*1e-7),
7555 (double)0,
7556 (double)0,
7557 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007558}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007559#else /* Neither Windows nor OS/2 */
7560#define NEED_TICKS_PER_SECOND
7561static long ticks_per_second = -1;
7562static PyObject *
7563posix_times(PyObject *self, PyObject *noargs)
7564{
7565 struct tms t;
7566 clock_t c;
7567 errno = 0;
7568 c = times(&t);
7569 if (c == (clock_t) -1)
7570 return posix_error();
7571 return build_times_result(
7572 (double)t.tms_utime / ticks_per_second,
7573 (double)t.tms_stime / ticks_per_second,
7574 (double)t.tms_cutime / ticks_per_second,
7575 (double)t.tms_cstime / ticks_per_second,
7576 (double)c / ticks_per_second);
7577}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007578#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007579
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007580#endif /* HAVE_TIMES */
7581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007582
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007583#ifdef HAVE_GETSID
7584PyDoc_STRVAR(posix_getsid__doc__,
7585"getsid(pid) -> sid\n\n\
7586Call the system call getsid().");
7587
7588static PyObject *
7589posix_getsid(PyObject *self, PyObject *args)
7590{
Victor Stinner8c62be82010-05-06 00:08:46 +00007591 pid_t pid;
7592 int sid;
7593 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7594 return NULL;
7595 sid = getsid(pid);
7596 if (sid < 0)
7597 return posix_error();
7598 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007599}
7600#endif /* HAVE_GETSID */
7601
7602
Guido van Rossumb6775db1994-08-01 11:34:53 +00007603#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007604PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007605"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007606Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007607
Barry Warsaw53699e91996-12-10 23:23:01 +00007608static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007609posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007610{
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 if (setsid() < 0)
7612 return posix_error();
7613 Py_INCREF(Py_None);
7614 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007615}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007616#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007617
Guido van Rossumb6775db1994-08-01 11:34:53 +00007618#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007619PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007620"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007621Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007622
Barry Warsaw53699e91996-12-10 23:23:01 +00007623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007624posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007625{
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 pid_t pid;
7627 int pgrp;
7628 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7629 return NULL;
7630 if (setpgid(pid, pgrp) < 0)
7631 return posix_error();
7632 Py_INCREF(Py_None);
7633 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007634}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007635#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007636
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007637
Guido van Rossumb6775db1994-08-01 11:34:53 +00007638#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007639PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007640"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007641Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007642
Barry Warsaw53699e91996-12-10 23:23:01 +00007643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007644posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007645{
Victor Stinner8c62be82010-05-06 00:08:46 +00007646 int fd;
7647 pid_t pgid;
7648 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7649 return NULL;
7650 pgid = tcgetpgrp(fd);
7651 if (pgid < 0)
7652 return posix_error();
7653 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007654}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007655#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007657
Guido van Rossumb6775db1994-08-01 11:34:53 +00007658#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007659PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007660"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007661Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007662
Barry Warsaw53699e91996-12-10 23:23:01 +00007663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007664posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007665{
Victor Stinner8c62be82010-05-06 00:08:46 +00007666 int fd;
7667 pid_t pgid;
7668 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7669 return NULL;
7670 if (tcsetpgrp(fd, pgid) < 0)
7671 return posix_error();
7672 Py_INCREF(Py_None);
7673 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007674}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007675#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007676
Guido van Rossum687dd131993-05-17 08:34:16 +00007677/* Functions acting on file descriptors */
7678
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007679PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007680"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7681Open a file for low level IO. Returns a file handle (integer).\n\
7682\n\
7683If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7684 and path should be relative; path will then be relative to that directory.\n\
7685dir_fd may not be implemented on your platform.\n\
7686 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007687
Barry Warsaw53699e91996-12-10 23:23:01 +00007688static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007689posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007690{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007691 path_t path;
7692 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007694 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007696 PyObject *return_value = NULL;
7697 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007698
Larry Hastings9cf065c2012-06-22 16:30:09 -07007699 memset(&path, 0, sizeof(path));
7700 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7701 path_converter, &path,
7702 &flags, &mode,
7703#ifdef HAVE_OPENAT
7704 dir_fd_converter, &dir_fd
7705#else
7706 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007707#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007708 ))
7709 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007710
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007712#ifdef MS_WINDOWS
7713 if (path.wide)
7714 fd = _wopen(path.wide, flags, mode);
7715 else
7716#endif
7717#ifdef HAVE_OPENAT
7718 if (dir_fd != DEFAULT_DIR_FD)
7719 fd = openat(dir_fd, path.narrow, flags, mode);
7720 else
7721#endif
7722 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007723 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007724
Larry Hastings9cf065c2012-06-22 16:30:09 -07007725 if (fd == -1) {
7726#ifdef MS_WINDOWS
7727 /* force use of posix_error here for exact backwards compatibility */
7728 if (path.wide)
7729 return_value = posix_error();
7730 else
7731#endif
7732 return_value = path_error("open", &path);
7733 goto exit;
7734 }
7735
7736 return_value = PyLong_FromLong((long)fd);
7737
7738exit:
7739 path_cleanup(&path);
7740 return return_value;
7741}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007742
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007743PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007744"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007745Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007746
Barry Warsaw53699e91996-12-10 23:23:01 +00007747static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007748posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007749{
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 int fd, res;
7751 if (!PyArg_ParseTuple(args, "i:close", &fd))
7752 return NULL;
7753 if (!_PyVerify_fd(fd))
7754 return posix_error();
7755 Py_BEGIN_ALLOW_THREADS
7756 res = close(fd);
7757 Py_END_ALLOW_THREADS
7758 if (res < 0)
7759 return posix_error();
7760 Py_INCREF(Py_None);
7761 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007762}
7763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007764
Victor Stinner8c62be82010-05-06 00:08:46 +00007765PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007766"closerange(fd_low, fd_high)\n\n\
7767Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7768
7769static PyObject *
7770posix_closerange(PyObject *self, PyObject *args)
7771{
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 int fd_from, fd_to, i;
7773 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7774 return NULL;
7775 Py_BEGIN_ALLOW_THREADS
7776 for (i = fd_from; i < fd_to; i++)
7777 if (_PyVerify_fd(i))
7778 close(i);
7779 Py_END_ALLOW_THREADS
7780 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007781}
7782
7783
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007784PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007785"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007786Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007787
Barry Warsaw53699e91996-12-10 23:23:01 +00007788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007789posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007790{
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 int fd;
7792 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7793 return NULL;
7794 if (!_PyVerify_fd(fd))
7795 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 if (fd < 0)
7798 return posix_error();
7799 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007800}
7801
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007802
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007803PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007804"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007805Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007806
Barry Warsaw53699e91996-12-10 23:23:01 +00007807static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007808posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007809{
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 int fd, fd2, res;
7811 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7812 return NULL;
7813 if (!_PyVerify_fd_dup2(fd, fd2))
7814 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 if (res < 0)
7817 return posix_error();
7818 Py_INCREF(Py_None);
7819 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007820}
7821
Ross Lagerwall7807c352011-03-17 20:20:30 +02007822#ifdef HAVE_LOCKF
7823PyDoc_STRVAR(posix_lockf__doc__,
7824"lockf(fd, cmd, len)\n\n\
7825Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7826fd is an open file descriptor.\n\
7827cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7828F_TEST.\n\
7829len specifies the section of the file to lock.");
7830
7831static PyObject *
7832posix_lockf(PyObject *self, PyObject *args)
7833{
7834 int fd, cmd, res;
7835 off_t len;
7836 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7837 &fd, &cmd, _parse_off_t, &len))
7838 return NULL;
7839
7840 Py_BEGIN_ALLOW_THREADS
7841 res = lockf(fd, cmd, len);
7842 Py_END_ALLOW_THREADS
7843
7844 if (res < 0)
7845 return posix_error();
7846
7847 Py_RETURN_NONE;
7848}
7849#endif
7850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007852PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007853"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007854Set the current position of a file descriptor.\n\
7855Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007856
Barry Warsaw53699e91996-12-10 23:23:01 +00007857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007858posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007859{
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007861#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007863#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007865#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007866 PyObject *posobj;
7867 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007868 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007869#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7871 switch (how) {
7872 case 0: how = SEEK_SET; break;
7873 case 1: how = SEEK_CUR; break;
7874 case 2: how = SEEK_END; break;
7875 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007876#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007877
Ross Lagerwall8e749672011-03-17 21:54:07 +02007878#if !defined(HAVE_LARGEFILE_SUPPORT)
7879 pos = PyLong_AsLong(posobj);
7880#else
7881 pos = PyLong_AsLongLong(posobj);
7882#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007883 if (PyErr_Occurred())
7884 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007885
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 if (!_PyVerify_fd(fd))
7887 return posix_error();
7888 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007889#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007891#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007892 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007893#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007894 Py_END_ALLOW_THREADS
7895 if (res < 0)
7896 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007897
7898#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007899 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007900#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007902#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007903}
7904
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007905
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007906PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007907"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007908Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007909
Barry Warsaw53699e91996-12-10 23:23:01 +00007910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007911posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007912{
Victor Stinner8c62be82010-05-06 00:08:46 +00007913 int fd, size;
7914 Py_ssize_t n;
7915 PyObject *buffer;
7916 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7917 return NULL;
7918 if (size < 0) {
7919 errno = EINVAL;
7920 return posix_error();
7921 }
7922 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7923 if (buffer == NULL)
7924 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007925 if (!_PyVerify_fd(fd)) {
7926 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007928 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 Py_BEGIN_ALLOW_THREADS
7930 n = read(fd, PyBytes_AS_STRING(buffer), size);
7931 Py_END_ALLOW_THREADS
7932 if (n < 0) {
7933 Py_DECREF(buffer);
7934 return posix_error();
7935 }
7936 if (n != size)
7937 _PyBytes_Resize(&buffer, n);
7938 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007939}
7940
Ross Lagerwall7807c352011-03-17 20:20:30 +02007941#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7942 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007943static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007944iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7945{
7946 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007947 Py_ssize_t blen, total = 0;
7948
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007949 *iov = PyMem_New(struct iovec, cnt);
7950 if (*iov == NULL) {
7951 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007952 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007953 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007954
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007955 *buf = PyMem_New(Py_buffer, cnt);
7956 if (*buf == NULL) {
7957 PyMem_Del(*iov);
7958 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007959 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007960 }
7961
7962 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007963 PyObject *item = PySequence_GetItem(seq, i);
7964 if (item == NULL)
7965 goto fail;
7966 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7967 Py_DECREF(item);
7968 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007969 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007970 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007971 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007972 blen = (*buf)[i].len;
7973 (*iov)[i].iov_len = blen;
7974 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007975 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007976 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007977
7978fail:
7979 PyMem_Del(*iov);
7980 for (j = 0; j < i; j++) {
7981 PyBuffer_Release(&(*buf)[j]);
7982 }
7983 PyMem_Del(*buf);
7984 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007985}
7986
7987static void
7988iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7989{
7990 int i;
7991 PyMem_Del(iov);
7992 for (i = 0; i < cnt; i++) {
7993 PyBuffer_Release(&buf[i]);
7994 }
7995 PyMem_Del(buf);
7996}
7997#endif
7998
Ross Lagerwall7807c352011-03-17 20:20:30 +02007999#ifdef HAVE_READV
8000PyDoc_STRVAR(posix_readv__doc__,
8001"readv(fd, buffers) -> bytesread\n\n\
8002Read from a file descriptor into a number of writable buffers. buffers\n\
8003is an arbitrary sequence of writable buffers.\n\
8004Returns the total number of bytes read.");
8005
8006static PyObject *
8007posix_readv(PyObject *self, PyObject *args)
8008{
8009 int fd, cnt;
8010 Py_ssize_t n;
8011 PyObject *seq;
8012 struct iovec *iov;
8013 Py_buffer *buf;
8014
8015 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8016 return NULL;
8017 if (!PySequence_Check(seq)) {
8018 PyErr_SetString(PyExc_TypeError,
8019 "readv() arg 2 must be a sequence");
8020 return NULL;
8021 }
8022 cnt = PySequence_Size(seq);
8023
8024 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
8025 return NULL;
8026
8027 Py_BEGIN_ALLOW_THREADS
8028 n = readv(fd, iov, cnt);
8029 Py_END_ALLOW_THREADS
8030
8031 iov_cleanup(iov, buf, cnt);
8032 return PyLong_FromSsize_t(n);
8033}
8034#endif
8035
8036#ifdef HAVE_PREAD
8037PyDoc_STRVAR(posix_pread__doc__,
8038"pread(fd, buffersize, offset) -> string\n\n\
8039Read from a file descriptor, fd, at a position of offset. It will read up\n\
8040to buffersize number of bytes. The file offset remains unchanged.");
8041
8042static PyObject *
8043posix_pread(PyObject *self, PyObject *args)
8044{
8045 int fd, size;
8046 off_t offset;
8047 Py_ssize_t n;
8048 PyObject *buffer;
8049 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8050 return NULL;
8051
8052 if (size < 0) {
8053 errno = EINVAL;
8054 return posix_error();
8055 }
8056 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8057 if (buffer == NULL)
8058 return NULL;
8059 if (!_PyVerify_fd(fd)) {
8060 Py_DECREF(buffer);
8061 return posix_error();
8062 }
8063 Py_BEGIN_ALLOW_THREADS
8064 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8065 Py_END_ALLOW_THREADS
8066 if (n < 0) {
8067 Py_DECREF(buffer);
8068 return posix_error();
8069 }
8070 if (n != size)
8071 _PyBytes_Resize(&buffer, n);
8072 return buffer;
8073}
8074#endif
8075
8076PyDoc_STRVAR(posix_write__doc__,
8077"write(fd, string) -> byteswritten\n\n\
8078Write a string to a file descriptor.");
8079
8080static PyObject *
8081posix_write(PyObject *self, PyObject *args)
8082{
8083 Py_buffer pbuf;
8084 int fd;
8085 Py_ssize_t size, len;
8086
8087 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8088 return NULL;
8089 if (!_PyVerify_fd(fd)) {
8090 PyBuffer_Release(&pbuf);
8091 return posix_error();
8092 }
8093 len = pbuf.len;
8094 Py_BEGIN_ALLOW_THREADS
8095#if defined(MS_WIN64) || defined(MS_WINDOWS)
8096 if (len > INT_MAX)
8097 len = INT_MAX;
8098 size = write(fd, pbuf.buf, (int)len);
8099#else
8100 size = write(fd, pbuf.buf, len);
8101#endif
8102 Py_END_ALLOW_THREADS
8103 PyBuffer_Release(&pbuf);
8104 if (size < 0)
8105 return posix_error();
8106 return PyLong_FromSsize_t(size);
8107}
8108
8109#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008110PyDoc_STRVAR(posix_sendfile__doc__,
8111"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8112sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8113 -> byteswritten\n\
8114Copy nbytes bytes from file descriptor in to file descriptor out.");
8115
8116static PyObject *
8117posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8118{
8119 int in, out;
8120 Py_ssize_t ret;
8121 off_t offset;
8122
8123#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8124#ifndef __APPLE__
8125 Py_ssize_t len;
8126#endif
8127 PyObject *headers = NULL, *trailers = NULL;
8128 Py_buffer *hbuf, *tbuf;
8129 off_t sbytes;
8130 struct sf_hdtr sf;
8131 int flags = 0;
8132 sf.headers = NULL;
8133 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008134 static char *keywords[] = {"out", "in",
8135 "offset", "count",
8136 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008137
8138#ifdef __APPLE__
8139 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008140 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008141#else
8142 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008143 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008144#endif
8145 &headers, &trailers, &flags))
8146 return NULL;
8147 if (headers != NULL) {
8148 if (!PySequence_Check(headers)) {
8149 PyErr_SetString(PyExc_TypeError,
8150 "sendfile() headers must be a sequence or None");
8151 return NULL;
8152 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008153 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008154 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008155 if (sf.hdr_cnt > 0 &&
8156 !(i = iov_setup(&(sf.headers), &hbuf,
8157 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008158 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008159#ifdef __APPLE__
8160 sbytes += i;
8161#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008162 }
8163 }
8164 if (trailers != NULL) {
8165 if (!PySequence_Check(trailers)) {
8166 PyErr_SetString(PyExc_TypeError,
8167 "sendfile() trailers must be a sequence or None");
8168 return NULL;
8169 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008170 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008171 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008172 if (sf.trl_cnt > 0 &&
8173 !(i = iov_setup(&(sf.trailers), &tbuf,
8174 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008175 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008176#ifdef __APPLE__
8177 sbytes += i;
8178#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008179 }
8180 }
8181
8182 Py_BEGIN_ALLOW_THREADS
8183#ifdef __APPLE__
8184 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8185#else
8186 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8187#endif
8188 Py_END_ALLOW_THREADS
8189
8190 if (sf.headers != NULL)
8191 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8192 if (sf.trailers != NULL)
8193 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8194
8195 if (ret < 0) {
8196 if ((errno == EAGAIN) || (errno == EBUSY)) {
8197 if (sbytes != 0) {
8198 // some data has been sent
8199 goto done;
8200 }
8201 else {
8202 // no data has been sent; upper application is supposed
8203 // to retry on EAGAIN or EBUSY
8204 return posix_error();
8205 }
8206 }
8207 return posix_error();
8208 }
8209 goto done;
8210
8211done:
8212 #if !defined(HAVE_LARGEFILE_SUPPORT)
8213 return Py_BuildValue("l", sbytes);
8214 #else
8215 return Py_BuildValue("L", sbytes);
8216 #endif
8217
8218#else
8219 Py_ssize_t count;
8220 PyObject *offobj;
8221 static char *keywords[] = {"out", "in",
8222 "offset", "count", NULL};
8223 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8224 keywords, &out, &in, &offobj, &count))
8225 return NULL;
8226#ifdef linux
8227 if (offobj == Py_None) {
8228 Py_BEGIN_ALLOW_THREADS
8229 ret = sendfile(out, in, NULL, count);
8230 Py_END_ALLOW_THREADS
8231 if (ret < 0)
8232 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008233 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008234 }
8235#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008236 if (!_parse_off_t(offobj, &offset))
8237 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008238 Py_BEGIN_ALLOW_THREADS
8239 ret = sendfile(out, in, &offset, count);
8240 Py_END_ALLOW_THREADS
8241 if (ret < 0)
8242 return posix_error();
8243 return Py_BuildValue("n", ret);
8244#endif
8245}
8246#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008248PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008249"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008250Like stat(), but for an open file descriptor.\n\
8251Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008252
Barry Warsaw53699e91996-12-10 23:23:01 +00008253static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008254posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008255{
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 int fd;
8257 STRUCT_STAT st;
8258 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008259 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008260 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008261#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 /* on OpenVMS we must ensure that all bytes are written to the file */
8263 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008264#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 Py_BEGIN_ALLOW_THREADS
8266 res = FSTAT(fd, &st);
8267 Py_END_ALLOW_THREADS
8268 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008269#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008270 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008271#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008272 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008273#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 }
Tim Peters5aa91602002-01-30 05:46:57 +00008275
Victor Stinner4195b5c2012-02-08 23:03:19 +01008276 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008277}
8278
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008279PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008280"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008281Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008282connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008283
8284static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008285posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008286{
Victor Stinner8c62be82010-05-06 00:08:46 +00008287 int fd;
8288 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8289 return NULL;
8290 if (!_PyVerify_fd(fd))
8291 return PyBool_FromLong(0);
8292 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008293}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008294
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008295#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008296PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008297"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008298Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008299
Barry Warsaw53699e91996-12-10 23:23:01 +00008300static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008301posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008302{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008303#if defined(PYOS_OS2)
8304 HFILE read, write;
8305 APIRET rc;
8306
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008307 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008308 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008309 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008310
8311 return Py_BuildValue("(ii)", read, write);
8312#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008313#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 int fds[2];
8315 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008316 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008317 if (res != 0)
8318 return posix_error();
8319 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008320#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008321 HANDLE read, write;
8322 int read_fd, write_fd;
8323 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008324 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008325 if (!ok)
8326 return win32_error("CreatePipe", NULL);
8327 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8328 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8329 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008330#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008331#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008332}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008333#endif /* HAVE_PIPE */
8334
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008335#ifdef HAVE_PIPE2
8336PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008337"pipe2(flags) -> (read_end, write_end)\n\n\
8338Create a pipe with flags set atomically.\n\
8339flags can be constructed by ORing together one or more of these values:\n\
8340O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008341");
8342
8343static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008344posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008345{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008346 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008347 int fds[2];
8348 int res;
8349
Charles-François Natali368f34b2011-06-06 19:49:47 +02008350 flags = PyLong_AsLong(arg);
8351 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008352 return NULL;
8353
8354 res = pipe2(fds, flags);
8355 if (res != 0)
8356 return posix_error();
8357 return Py_BuildValue("(ii)", fds[0], fds[1]);
8358}
8359#endif /* HAVE_PIPE2 */
8360
Ross Lagerwall7807c352011-03-17 20:20:30 +02008361#ifdef HAVE_WRITEV
8362PyDoc_STRVAR(posix_writev__doc__,
8363"writev(fd, buffers) -> byteswritten\n\n\
8364Write the contents of buffers to a file descriptor, where buffers is an\n\
8365arbitrary sequence of buffers.\n\
8366Returns the total bytes written.");
8367
8368static PyObject *
8369posix_writev(PyObject *self, PyObject *args)
8370{
8371 int fd, cnt;
8372 Py_ssize_t res;
8373 PyObject *seq;
8374 struct iovec *iov;
8375 Py_buffer *buf;
8376 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8377 return NULL;
8378 if (!PySequence_Check(seq)) {
8379 PyErr_SetString(PyExc_TypeError,
8380 "writev() arg 2 must be a sequence");
8381 return NULL;
8382 }
8383 cnt = PySequence_Size(seq);
8384
8385 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8386 return NULL;
8387 }
8388
8389 Py_BEGIN_ALLOW_THREADS
8390 res = writev(fd, iov, cnt);
8391 Py_END_ALLOW_THREADS
8392
8393 iov_cleanup(iov, buf, cnt);
8394 return PyLong_FromSsize_t(res);
8395}
8396#endif
8397
8398#ifdef HAVE_PWRITE
8399PyDoc_STRVAR(posix_pwrite__doc__,
8400"pwrite(fd, string, offset) -> byteswritten\n\n\
8401Write string to a file descriptor, fd, from offset, leaving the file\n\
8402offset unchanged.");
8403
8404static PyObject *
8405posix_pwrite(PyObject *self, PyObject *args)
8406{
8407 Py_buffer pbuf;
8408 int fd;
8409 off_t offset;
8410 Py_ssize_t size;
8411
8412 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8413 return NULL;
8414
8415 if (!_PyVerify_fd(fd)) {
8416 PyBuffer_Release(&pbuf);
8417 return posix_error();
8418 }
8419 Py_BEGIN_ALLOW_THREADS
8420 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8421 Py_END_ALLOW_THREADS
8422 PyBuffer_Release(&pbuf);
8423 if (size < 0)
8424 return posix_error();
8425 return PyLong_FromSsize_t(size);
8426}
8427#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008428
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008429#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008430PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008431"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8432Create a FIFO (a POSIX named pipe).\n\
8433\n\
8434If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8435 and path should be relative; path will then be relative to that directory.\n\
8436dir_fd may not be implemented on your platform.\n\
8437 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008438
Barry Warsaw53699e91996-12-10 23:23:01 +00008439static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008440posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008441{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008442 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008444 int dir_fd = DEFAULT_DIR_FD;
8445 int result;
8446 PyObject *return_value = NULL;
8447 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8448
8449 memset(&path, 0, sizeof(path));
8450 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8451 path_converter, &path,
8452 &mode,
8453#ifdef HAVE_MKFIFOAT
8454 dir_fd_converter, &dir_fd
8455#else
8456 dir_fd_unavailable, &dir_fd
8457#endif
8458 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008459 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008460
Victor Stinner8c62be82010-05-06 00:08:46 +00008461 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008462#ifdef HAVE_MKFIFOAT
8463 if (dir_fd != DEFAULT_DIR_FD)
8464 result = mkfifoat(dir_fd, path.narrow, mode);
8465 else
8466#endif
8467 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008468 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008469
8470 if (result < 0) {
8471 return_value = posix_error();
8472 goto exit;
8473 }
8474
8475 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008476 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008477
8478exit:
8479 path_cleanup(&path);
8480 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008481}
8482#endif
8483
Neal Norwitz11690112002-07-30 01:08:28 +00008484#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008485PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008486"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008487Create a filesystem node (file, device special file or named pipe)\n\
8488named filename. mode specifies both the permissions to use and the\n\
8489type of node to be created, being combined (bitwise OR) with one of\n\
8490S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008491device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008492os.makedev()), otherwise it is ignored.\n\
8493\n\
8494If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8495 and path should be relative; path will then be relative to that directory.\n\
8496dir_fd may not be implemented on your platform.\n\
8497 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008498
8499
8500static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008501posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008502{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008503 path_t path;
8504 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008506 int dir_fd = DEFAULT_DIR_FD;
8507 int result;
8508 PyObject *return_value = NULL;
8509 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8510
8511 memset(&path, 0, sizeof(path));
8512 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8513 path_converter, &path,
8514 &mode, &device,
8515#ifdef HAVE_MKNODAT
8516 dir_fd_converter, &dir_fd
8517#else
8518 dir_fd_unavailable, &dir_fd
8519#endif
8520 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008521 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008522
Victor Stinner8c62be82010-05-06 00:08:46 +00008523 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008524#ifdef HAVE_MKNODAT
8525 if (dir_fd != DEFAULT_DIR_FD)
8526 result = mknodat(dir_fd, path.narrow, mode, device);
8527 else
8528#endif
8529 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008530 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008531
8532 if (result < 0) {
8533 return_value = posix_error();
8534 goto exit;
8535 }
8536
8537 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008538 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008539
Larry Hastings9cf065c2012-06-22 16:30:09 -07008540exit:
8541 path_cleanup(&path);
8542 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008543}
8544#endif
8545
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008546#ifdef HAVE_DEVICE_MACROS
8547PyDoc_STRVAR(posix_major__doc__,
8548"major(device) -> major number\n\
8549Extracts a device major number from a raw device number.");
8550
8551static PyObject *
8552posix_major(PyObject *self, PyObject *args)
8553{
Victor Stinner8c62be82010-05-06 00:08:46 +00008554 int device;
8555 if (!PyArg_ParseTuple(args, "i:major", &device))
8556 return NULL;
8557 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008558}
8559
8560PyDoc_STRVAR(posix_minor__doc__,
8561"minor(device) -> minor number\n\
8562Extracts a device minor number from a raw device number.");
8563
8564static PyObject *
8565posix_minor(PyObject *self, PyObject *args)
8566{
Victor Stinner8c62be82010-05-06 00:08:46 +00008567 int device;
8568 if (!PyArg_ParseTuple(args, "i:minor", &device))
8569 return NULL;
8570 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008571}
8572
8573PyDoc_STRVAR(posix_makedev__doc__,
8574"makedev(major, minor) -> device number\n\
8575Composes a raw device number from the major and minor device numbers.");
8576
8577static PyObject *
8578posix_makedev(PyObject *self, PyObject *args)
8579{
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 int major, minor;
8581 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8582 return NULL;
8583 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008584}
8585#endif /* device macros */
8586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008587
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008588#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008589PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008590"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008591Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008592
Barry Warsaw53699e91996-12-10 23:23:01 +00008593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008594posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008595{
Victor Stinner8c62be82010-05-06 00:08:46 +00008596 int fd;
8597 off_t length;
8598 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008599
Ross Lagerwall7807c352011-03-17 20:20:30 +02008600 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008601 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008602
Victor Stinner8c62be82010-05-06 00:08:46 +00008603 Py_BEGIN_ALLOW_THREADS
8604 res = ftruncate(fd, length);
8605 Py_END_ALLOW_THREADS
8606 if (res < 0)
8607 return posix_error();
8608 Py_INCREF(Py_None);
8609 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008610}
8611#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008612
Ross Lagerwall7807c352011-03-17 20:20:30 +02008613#ifdef HAVE_TRUNCATE
8614PyDoc_STRVAR(posix_truncate__doc__,
8615"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008616Truncate the file given by path to length bytes.\n\
8617On some platforms, path may also be specified as an open file descriptor.\n\
8618 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008619
8620static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008621posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008622{
Georg Brandl306336b2012-06-24 12:55:33 +02008623 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008624 off_t length;
8625 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008626 PyObject *result = NULL;
8627 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008628
Georg Brandl306336b2012-06-24 12:55:33 +02008629 memset(&path, 0, sizeof(path));
8630#ifdef HAVE_FTRUNCATE
8631 path.allow_fd = 1;
8632#endif
8633 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8634 path_converter, &path,
8635 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008636 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008637
8638 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008639#ifdef HAVE_FTRUNCATE
8640 if (path.fd != -1)
8641 res = ftruncate(path.fd, length);
8642 else
8643#endif
8644 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008645 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008646 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008647 result = path_posix_error("truncate", &path);
8648 else {
8649 Py_INCREF(Py_None);
8650 result = Py_None;
8651 }
8652 path_cleanup(&path);
8653 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008654}
8655#endif
8656
8657#ifdef HAVE_POSIX_FALLOCATE
8658PyDoc_STRVAR(posix_posix_fallocate__doc__,
8659"posix_fallocate(fd, offset, len)\n\n\
8660Ensures that enough disk space is allocated for the file specified by fd\n\
8661starting from offset and continuing for len bytes.");
8662
8663static PyObject *
8664posix_posix_fallocate(PyObject *self, PyObject *args)
8665{
8666 off_t len, offset;
8667 int res, fd;
8668
8669 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8670 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8671 return NULL;
8672
8673 Py_BEGIN_ALLOW_THREADS
8674 res = posix_fallocate(fd, offset, len);
8675 Py_END_ALLOW_THREADS
8676 if (res != 0) {
8677 errno = res;
8678 return posix_error();
8679 }
8680 Py_RETURN_NONE;
8681}
8682#endif
8683
8684#ifdef HAVE_POSIX_FADVISE
8685PyDoc_STRVAR(posix_posix_fadvise__doc__,
8686"posix_fadvise(fd, offset, len, advice)\n\n\
8687Announces an intention to access data in a specific pattern thus allowing\n\
8688the kernel to make optimizations.\n\
8689The advice applies to the region of the file specified by fd starting at\n\
8690offset and continuing for len bytes.\n\
8691advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8692POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8693POSIX_FADV_DONTNEED.");
8694
8695static PyObject *
8696posix_posix_fadvise(PyObject *self, PyObject *args)
8697{
8698 off_t len, offset;
8699 int res, fd, advice;
8700
8701 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8702 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8703 return NULL;
8704
8705 Py_BEGIN_ALLOW_THREADS
8706 res = posix_fadvise(fd, offset, len, advice);
8707 Py_END_ALLOW_THREADS
8708 if (res != 0) {
8709 errno = res;
8710 return posix_error();
8711 }
8712 Py_RETURN_NONE;
8713}
8714#endif
8715
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008716#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008717PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008718"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008719Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008720
Fred Drake762e2061999-08-26 17:23:54 +00008721/* Save putenv() parameters as values here, so we can collect them when they
8722 * get re-set with another call for the same key. */
8723static PyObject *posix_putenv_garbage;
8724
Tim Peters5aa91602002-01-30 05:46:57 +00008725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008726posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008727{
Victor Stinner84ae1182010-05-06 22:05:07 +00008728 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008729#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008730 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008731 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008732
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008734 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008735 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008737
Victor Stinner65170952011-11-22 22:16:17 +01008738 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008739 if (newstr == NULL) {
8740 PyErr_NoMemory();
8741 goto error;
8742 }
Victor Stinner65170952011-11-22 22:16:17 +01008743 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8744 PyErr_Format(PyExc_ValueError,
8745 "the environment variable is longer than %u characters",
8746 _MAX_ENV);
8747 goto error;
8748 }
8749
Victor Stinner8c62be82010-05-06 00:08:46 +00008750 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008751 if (newenv == NULL)
8752 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008753 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008755 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008756 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008757#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008758 PyObject *os1, *os2;
8759 char *s1, *s2;
8760 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008761
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008762 if (!PyArg_ParseTuple(args,
8763 "O&O&:putenv",
8764 PyUnicode_FSConverter, &os1,
8765 PyUnicode_FSConverter, &os2))
8766 return NULL;
8767 s1 = PyBytes_AsString(os1);
8768 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008769
Victor Stinner65170952011-11-22 22:16:17 +01008770 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008771 if (newstr == NULL) {
8772 PyErr_NoMemory();
8773 goto error;
8774 }
8775
Victor Stinner8c62be82010-05-06 00:08:46 +00008776 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008777 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008779 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008780 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008781#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008782
Victor Stinner8c62be82010-05-06 00:08:46 +00008783 /* Install the first arg and newstr in posix_putenv_garbage;
8784 * this will cause previous value to be collected. This has to
8785 * happen after the real putenv() call because the old value
8786 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008787 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008788 /* really not much we can do; just leak */
8789 PyErr_Clear();
8790 }
8791 else {
8792 Py_DECREF(newstr);
8793 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008794
Martin v. Löwis011e8422009-05-05 04:43:17 +00008795#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 Py_DECREF(os1);
8797 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008798#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008799 Py_RETURN_NONE;
8800
8801error:
8802#ifndef MS_WINDOWS
8803 Py_DECREF(os1);
8804 Py_DECREF(os2);
8805#endif
8806 Py_XDECREF(newstr);
8807 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008808}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008809#endif /* putenv */
8810
Guido van Rossumc524d952001-10-19 01:31:59 +00008811#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008812PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008813"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008814Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008815
8816static PyObject *
8817posix_unsetenv(PyObject *self, PyObject *args)
8818{
Victor Stinner65170952011-11-22 22:16:17 +01008819 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008820#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008821 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008822#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008823
8824 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008825
Victor Stinner65170952011-11-22 22:16:17 +01008826 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008827 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008828
Victor Stinner984890f2011-11-24 13:53:38 +01008829#ifdef HAVE_BROKEN_UNSETENV
8830 unsetenv(PyBytes_AS_STRING(name));
8831#else
Victor Stinner65170952011-11-22 22:16:17 +01008832 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008833 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008834 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008835 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008836 }
Victor Stinner984890f2011-11-24 13:53:38 +01008837#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008838
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 /* Remove the key from posix_putenv_garbage;
8840 * this will cause it to be collected. This has to
8841 * happen after the real unsetenv() call because the
8842 * old value was still accessible until then.
8843 */
Victor Stinner65170952011-11-22 22:16:17 +01008844 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008845 /* really not much we can do; just leak */
8846 PyErr_Clear();
8847 }
Victor Stinner65170952011-11-22 22:16:17 +01008848 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008849 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008850}
8851#endif /* unsetenv */
8852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008853PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008854"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008855Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008856
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008858posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008859{
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 int code;
8861 char *message;
8862 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8863 return NULL;
8864 message = strerror(code);
8865 if (message == NULL) {
8866 PyErr_SetString(PyExc_ValueError,
8867 "strerror() argument out of range");
8868 return NULL;
8869 }
Victor Stinner1b579672011-12-17 05:47:23 +01008870 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008871}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008872
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008873
Guido van Rossumc9641791998-08-04 15:26:23 +00008874#ifdef HAVE_SYS_WAIT_H
8875
Fred Drake106c1a02002-04-23 15:58:02 +00008876#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008877PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008878"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008879Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008880
8881static PyObject *
8882posix_WCOREDUMP(PyObject *self, PyObject *args)
8883{
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 WAIT_TYPE status;
8885 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008886
Victor Stinner8c62be82010-05-06 00:08:46 +00008887 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8888 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008889
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008891}
8892#endif /* WCOREDUMP */
8893
8894#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008895PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008896"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008897Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008898job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008899
8900static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008901posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008902{
Victor Stinner8c62be82010-05-06 00:08:46 +00008903 WAIT_TYPE status;
8904 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008905
Victor Stinner8c62be82010-05-06 00:08:46 +00008906 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8907 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008908
Victor Stinner8c62be82010-05-06 00:08:46 +00008909 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008910}
8911#endif /* WIFCONTINUED */
8912
Guido van Rossumc9641791998-08-04 15:26:23 +00008913#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008914PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008915"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008916Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008917
8918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008919posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008920{
Victor Stinner8c62be82010-05-06 00:08:46 +00008921 WAIT_TYPE status;
8922 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008923
Victor Stinner8c62be82010-05-06 00:08:46 +00008924 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8925 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008926
Victor Stinner8c62be82010-05-06 00:08:46 +00008927 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008928}
8929#endif /* WIFSTOPPED */
8930
8931#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008932PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008933"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008934Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008935
8936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008937posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008938{
Victor Stinner8c62be82010-05-06 00:08:46 +00008939 WAIT_TYPE status;
8940 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008941
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8943 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008944
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008946}
8947#endif /* WIFSIGNALED */
8948
8949#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008950PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008951"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008952Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008953system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008954
8955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008956posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008957{
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 WAIT_TYPE status;
8959 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008960
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8962 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008963
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008965}
8966#endif /* WIFEXITED */
8967
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008968#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008969PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008970"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008971Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008972
8973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008974posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008975{
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 WAIT_TYPE status;
8977 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008978
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8980 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008981
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008983}
8984#endif /* WEXITSTATUS */
8985
8986#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008987PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008988"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008989Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008990value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008991
8992static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008993posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008994{
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 WAIT_TYPE status;
8996 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008997
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8999 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009000
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009002}
9003#endif /* WTERMSIG */
9004
9005#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009006PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009007"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009008Return the signal that stopped the process that provided\n\
9009the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009010
9011static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009012posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009013{
Victor Stinner8c62be82010-05-06 00:08:46 +00009014 WAIT_TYPE status;
9015 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009016
Victor Stinner8c62be82010-05-06 00:08:46 +00009017 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9018 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009019
Victor Stinner8c62be82010-05-06 00:08:46 +00009020 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009021}
9022#endif /* WSTOPSIG */
9023
9024#endif /* HAVE_SYS_WAIT_H */
9025
9026
Thomas Wouters477c8d52006-05-27 19:21:47 +00009027#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009028#ifdef _SCO_DS
9029/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9030 needed definitions in sys/statvfs.h */
9031#define _SVID3
9032#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009033#include <sys/statvfs.h>
9034
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009035static PyObject*
9036_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9038 if (v == NULL)
9039 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009040
9041#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9043 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9044 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9045 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9046 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9047 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9048 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9049 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9050 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9051 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009052#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9054 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9055 PyStructSequence_SET_ITEM(v, 2,
9056 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9057 PyStructSequence_SET_ITEM(v, 3,
9058 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9059 PyStructSequence_SET_ITEM(v, 4,
9060 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9061 PyStructSequence_SET_ITEM(v, 5,
9062 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9063 PyStructSequence_SET_ITEM(v, 6,
9064 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9065 PyStructSequence_SET_ITEM(v, 7,
9066 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9067 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9068 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009069#endif
9070
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009072}
9073
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009074PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009075"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009076Perform an fstatvfs system call on the given fd.\n\
9077Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009078
9079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009080posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009081{
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 int fd, res;
9083 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009084
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9086 return NULL;
9087 Py_BEGIN_ALLOW_THREADS
9088 res = fstatvfs(fd, &st);
9089 Py_END_ALLOW_THREADS
9090 if (res != 0)
9091 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009092
Victor Stinner8c62be82010-05-06 00:08:46 +00009093 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009094}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009095#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009096
9097
Thomas Wouters477c8d52006-05-27 19:21:47 +00009098#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009099#include <sys/statvfs.h>
9100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009101PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009102"statvfs(path)\n\n\
9103Perform a statvfs system call on the given path.\n\
9104\n\
9105path may always be specified as a string.\n\
9106On some platforms, path may also be specified as an open file descriptor.\n\
9107 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009108
9109static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009110posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009111{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009112 static char *keywords[] = {"path", NULL};
9113 path_t path;
9114 int result;
9115 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009117
Larry Hastings9cf065c2012-06-22 16:30:09 -07009118 memset(&path, 0, sizeof(path));
9119#ifdef HAVE_FSTATVFS
9120 path.allow_fd = 1;
9121#endif
9122 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9123 path_converter, &path
9124 ))
9125 return NULL;
9126
9127 Py_BEGIN_ALLOW_THREADS
9128#ifdef HAVE_FSTATVFS
9129 if (path.fd != -1) {
9130#ifdef __APPLE__
9131 /* handle weak-linking on Mac OS X 10.3 */
9132 if (fstatvfs == NULL) {
9133 fd_specified("statvfs", path.fd);
9134 goto exit;
9135 }
9136#endif
9137 result = fstatvfs(path.fd, &st);
9138 }
9139 else
9140#endif
9141 result = statvfs(path.narrow, &st);
9142 Py_END_ALLOW_THREADS
9143
9144 if (result) {
9145 return_value = path_posix_error("statvfs", &path);
9146 goto exit;
9147 }
9148
9149 return_value = _pystatvfs_fromstructstatvfs(st);
9150
9151exit:
9152 path_cleanup(&path);
9153 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009154}
9155#endif /* HAVE_STATVFS */
9156
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009157#ifdef MS_WINDOWS
9158PyDoc_STRVAR(win32__getdiskusage__doc__,
9159"_getdiskusage(path) -> (total, free)\n\n\
9160Return disk usage statistics about the given path as (total, free) tuple.");
9161
9162static PyObject *
9163win32__getdiskusage(PyObject *self, PyObject *args)
9164{
9165 BOOL retval;
9166 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009167 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009168
Victor Stinner6139c1b2011-11-09 22:14:14 +01009169 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009170 return NULL;
9171
9172 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009173 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009174 Py_END_ALLOW_THREADS
9175 if (retval == 0)
9176 return PyErr_SetFromWindowsErr(0);
9177
9178 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9179}
9180#endif
9181
9182
Fred Drakec9680921999-12-13 16:37:25 +00009183/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9184 * It maps strings representing configuration variable names to
9185 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009186 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009187 * rarely-used constants. There are three separate tables that use
9188 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009189 *
9190 * This code is always included, even if none of the interfaces that
9191 * need it are included. The #if hackery needed to avoid it would be
9192 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009193 */
9194struct constdef {
9195 char *name;
9196 long value;
9197};
9198
Fred Drake12c6e2d1999-12-14 21:25:03 +00009199static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009200conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009201 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009202{
Christian Heimes217cfd12007-12-02 14:31:20 +00009203 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009204 *valuep = PyLong_AS_LONG(arg);
9205 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009206 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009207 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009208 /* look up the value in the table using a binary search */
9209 size_t lo = 0;
9210 size_t mid;
9211 size_t hi = tablesize;
9212 int cmp;
9213 const char *confname;
9214 if (!PyUnicode_Check(arg)) {
9215 PyErr_SetString(PyExc_TypeError,
9216 "configuration names must be strings or integers");
9217 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009219 confname = _PyUnicode_AsString(arg);
9220 if (confname == NULL)
9221 return 0;
9222 while (lo < hi) {
9223 mid = (lo + hi) / 2;
9224 cmp = strcmp(confname, table[mid].name);
9225 if (cmp < 0)
9226 hi = mid;
9227 else if (cmp > 0)
9228 lo = mid + 1;
9229 else {
9230 *valuep = table[mid].value;
9231 return 1;
9232 }
9233 }
9234 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9235 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009236 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009237}
9238
9239
9240#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9241static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009242#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009244#endif
9245#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009246 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009247#endif
Fred Drakec9680921999-12-13 16:37:25 +00009248#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009249 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009250#endif
9251#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009252 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009253#endif
9254#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009255 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009256#endif
9257#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009259#endif
9260#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009261 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009262#endif
9263#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009264 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009265#endif
9266#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009267 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009268#endif
9269#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009270 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009271#endif
9272#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009273 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009274#endif
9275#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009277#endif
9278#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009280#endif
9281#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009283#endif
9284#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009286#endif
9287#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009289#endif
9290#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009291 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009292#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009293#ifdef _PC_ACL_ENABLED
9294 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9295#endif
9296#ifdef _PC_MIN_HOLE_SIZE
9297 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9298#endif
9299#ifdef _PC_ALLOC_SIZE_MIN
9300 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9301#endif
9302#ifdef _PC_REC_INCR_XFER_SIZE
9303 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9304#endif
9305#ifdef _PC_REC_MAX_XFER_SIZE
9306 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9307#endif
9308#ifdef _PC_REC_MIN_XFER_SIZE
9309 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9310#endif
9311#ifdef _PC_REC_XFER_ALIGN
9312 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9313#endif
9314#ifdef _PC_SYMLINK_MAX
9315 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9316#endif
9317#ifdef _PC_XATTR_ENABLED
9318 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9319#endif
9320#ifdef _PC_XATTR_EXISTS
9321 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9322#endif
9323#ifdef _PC_TIMESTAMP_RESOLUTION
9324 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9325#endif
Fred Drakec9680921999-12-13 16:37:25 +00009326};
9327
Fred Drakec9680921999-12-13 16:37:25 +00009328static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009329conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009330{
9331 return conv_confname(arg, valuep, posix_constants_pathconf,
9332 sizeof(posix_constants_pathconf)
9333 / sizeof(struct constdef));
9334}
9335#endif
9336
9337#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009338PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009339"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009340Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009341If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009342
9343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009344posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009345{
9346 PyObject *result = NULL;
9347 int name, fd;
9348
Fred Drake12c6e2d1999-12-14 21:25:03 +00009349 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9350 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009351 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009352
Stefan Krah0e803b32010-11-26 16:16:47 +00009353 errno = 0;
9354 limit = fpathconf(fd, name);
9355 if (limit == -1 && errno != 0)
9356 posix_error();
9357 else
9358 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009359 }
9360 return result;
9361}
9362#endif
9363
9364
9365#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009366PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009367"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009368Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009369If there is no limit, return -1.\n\
9370On some platforms, path may also be specified as an open file descriptor.\n\
9371 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009372
9373static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009374posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009375{
Georg Brandl306336b2012-06-24 12:55:33 +02009376 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009377 PyObject *result = NULL;
9378 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009379 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009380
Georg Brandl306336b2012-06-24 12:55:33 +02009381 memset(&path, 0, sizeof(path));
9382#ifdef HAVE_FPATHCONF
9383 path.allow_fd = 1;
9384#endif
9385 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9386 path_converter, &path,
9387 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009389
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009391#ifdef HAVE_FPATHCONF
9392 if (path.fd != -1)
9393 limit = fpathconf(path.fd, name);
9394 else
9395#endif
9396 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 if (limit == -1 && errno != 0) {
9398 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009399 /* could be a path or name problem */
9400 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009401 else
Georg Brandl306336b2012-06-24 12:55:33 +02009402 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 }
9404 else
9405 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009406 }
Georg Brandl306336b2012-06-24 12:55:33 +02009407 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009408 return result;
9409}
9410#endif
9411
9412#ifdef HAVE_CONFSTR
9413static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009414#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009416#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009417#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009419#endif
9420#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009422#endif
Fred Draked86ed291999-12-15 15:34:33 +00009423#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009425#endif
9426#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009428#endif
9429#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009431#endif
9432#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009434#endif
Fred Drakec9680921999-12-13 16:37:25 +00009435#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009437#endif
9438#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009440#endif
9441#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009443#endif
9444#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009446#endif
9447#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009449#endif
9450#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009452#endif
9453#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009455#endif
9456#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009458#endif
Fred Draked86ed291999-12-15 15:34:33 +00009459#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009461#endif
Fred Drakec9680921999-12-13 16:37:25 +00009462#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009464#endif
Fred Draked86ed291999-12-15 15:34:33 +00009465#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009467#endif
9468#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009470#endif
9471#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009473#endif
9474#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009476#endif
Fred Drakec9680921999-12-13 16:37:25 +00009477#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009479#endif
9480#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009482#endif
9483#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009485#endif
9486#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009488#endif
9489#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009491#endif
9492#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009493 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009494#endif
9495#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009497#endif
9498#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009500#endif
9501#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009503#endif
9504#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009506#endif
9507#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009509#endif
9510#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009512#endif
9513#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009515#endif
9516#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009518#endif
9519#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009521#endif
9522#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009524#endif
Fred Draked86ed291999-12-15 15:34:33 +00009525#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009527#endif
9528#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009530#endif
9531#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009533#endif
9534#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009536#endif
9537#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009539#endif
9540#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009542#endif
9543#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009545#endif
9546#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009548#endif
9549#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009551#endif
9552#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009554#endif
9555#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009557#endif
9558#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009560#endif
9561#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009563#endif
Fred Drakec9680921999-12-13 16:37:25 +00009564};
9565
9566static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009567conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009568{
9569 return conv_confname(arg, valuep, posix_constants_confstr,
9570 sizeof(posix_constants_confstr)
9571 / sizeof(struct constdef));
9572}
9573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009574PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009575"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009576Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009577
9578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009579posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009580{
9581 PyObject *result = NULL;
9582 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009583 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009584 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009585
Victor Stinnercb043522010-09-10 23:49:04 +00009586 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9587 return NULL;
9588
9589 errno = 0;
9590 len = confstr(name, buffer, sizeof(buffer));
9591 if (len == 0) {
9592 if (errno) {
9593 posix_error();
9594 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009595 }
9596 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009597 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009598 }
9599 }
Victor Stinnercb043522010-09-10 23:49:04 +00009600
9601 if ((unsigned int)len >= sizeof(buffer)) {
9602 char *buf = PyMem_Malloc(len);
9603 if (buf == NULL)
9604 return PyErr_NoMemory();
9605 confstr(name, buf, len);
9606 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9607 PyMem_Free(buf);
9608 }
9609 else
9610 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009611 return result;
9612}
9613#endif
9614
9615
9616#ifdef HAVE_SYSCONF
9617static struct constdef posix_constants_sysconf[] = {
9618#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
9639#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
Fred Draked86ed291999-12-15 15:34:33 +00009648#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009650#endif
9651#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009653#endif
Fred Drakec9680921999-12-13 16:37:25 +00009654#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
Fred Drakec9680921999-12-13 16:37:25 +00009657#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
9666#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009668#endif
9669#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009671#endif
Fred Draked86ed291999-12-15 15:34:33 +00009672#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009674#endif
Fred Drakec9680921999-12-13 16:37:25 +00009675#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009677#endif
9678#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009680#endif
9681#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009683#endif
9684#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009686#endif
9687#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009689#endif
Fred Draked86ed291999-12-15 15:34:33 +00009690#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009692#endif
Fred Drakec9680921999-12-13 16:37:25 +00009693#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
9696#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009698#endif
9699#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009701#endif
9702#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009704#endif
9705#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
9708#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009710#endif
9711#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
9714#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009716#endif
9717#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
Fred Draked86ed291999-12-15 15:34:33 +00009762#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009764#endif
Fred Drakec9680921999-12-13 16:37:25 +00009765#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
Fred Draked86ed291999-12-15 15:34:33 +00009774#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009776#endif
Fred Drakec9680921999-12-13 16:37:25 +00009777#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
Fred Draked86ed291999-12-15 15:34:33 +00009780#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009782#endif
9783#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009785#endif
Fred Drakec9680921999-12-13 16:37:25 +00009786#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
Fred Draked86ed291999-12-15 15:34:33 +00009798#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009800#endif
Fred Drakec9680921999-12-13 16:37:25 +00009801#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
Fred Draked86ed291999-12-15 15:34:33 +00009822#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009824#endif
Fred Drakec9680921999-12-13 16:37:25 +00009825#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
Fred Draked86ed291999-12-15 15:34:33 +00009831#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009833#endif
Fred Drakec9680921999-12-13 16:37:25 +00009834#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
Fred Draked86ed291999-12-15 15:34:33 +00009861#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009863#endif
9864#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009866#endif
Fred Drakec9680921999-12-13 16:37:25 +00009867#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
Fred Draked86ed291999-12-15 15:34:33 +00009972#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009974#endif
Fred Drakec9680921999-12-13 16:37:25 +00009975#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
10089#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110};
10111
10112static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010113conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010114{
10115 return conv_confname(arg, valuep, posix_constants_sysconf,
10116 sizeof(posix_constants_sysconf)
10117 / sizeof(struct constdef));
10118}
10119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010120PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010121"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010122Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010123
10124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010125posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010126{
10127 PyObject *result = NULL;
10128 int name;
10129
10130 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10131 int value;
10132
10133 errno = 0;
10134 value = sysconf(name);
10135 if (value == -1 && errno != 0)
10136 posix_error();
10137 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010138 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010139 }
10140 return result;
10141}
10142#endif
10143
10144
Fred Drakebec628d1999-12-15 18:31:10 +000010145/* This code is used to ensure that the tables of configuration value names
10146 * are in sorted order as required by conv_confname(), and also to build the
10147 * the exported dictionaries that are used to publish information about the
10148 * names available on the host platform.
10149 *
10150 * Sorting the table at runtime ensures that the table is properly ordered
10151 * when used, even for platforms we're not able to test on. It also makes
10152 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010153 */
Fred Drakebec628d1999-12-15 18:31:10 +000010154
10155static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010156cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010157{
10158 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010160 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010162
10163 return strcmp(c1->name, c2->name);
10164}
10165
10166static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010167setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010169{
Fred Drakebec628d1999-12-15 18:31:10 +000010170 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010171 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010172
10173 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10174 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010175 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010177
Barry Warsaw3155db32000-04-13 15:20:40 +000010178 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 PyObject *o = PyLong_FromLong(table[i].value);
10180 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10181 Py_XDECREF(o);
10182 Py_DECREF(d);
10183 return -1;
10184 }
10185 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010186 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010187 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010188}
10189
Fred Drakebec628d1999-12-15 18:31:10 +000010190/* Return -1 on failure, 0 on success. */
10191static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010192setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010193{
10194#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010195 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010196 sizeof(posix_constants_pathconf)
10197 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010198 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010199 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010200#endif
10201#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010202 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010203 sizeof(posix_constants_confstr)
10204 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010205 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010206 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010207#endif
10208#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010209 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010210 sizeof(posix_constants_sysconf)
10211 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010212 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010213 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010214#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010215 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010216}
Fred Draked86ed291999-12-15 15:34:33 +000010217
10218
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010219PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010220"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010221Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010222in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010223
10224static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010225posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010226{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010227 abort();
10228 /*NOTREACHED*/
10229 Py_FatalError("abort() called from Python code didn't abort!");
10230 return NULL;
10231}
Fred Drakebec628d1999-12-15 18:31:10 +000010232
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010233#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010234PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010235"startfile(filepath [, operation]) - Start a file with its associated\n\
10236application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010237\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010238When \"operation\" is not specified or \"open\", this acts like\n\
10239double-clicking the file in Explorer, or giving the file name as an\n\
10240argument to the DOS \"start\" command: the file is opened with whatever\n\
10241application (if any) its extension is associated.\n\
10242When another \"operation\" is given, it specifies what should be done with\n\
10243the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010244\n\
10245startfile returns as soon as the associated application is launched.\n\
10246There is no option to wait for the application to close, and no way\n\
10247to retrieve the application's exit status.\n\
10248\n\
10249The filepath is relative to the current directory. If you want to use\n\
10250an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010251the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010252
10253static PyObject *
10254win32_startfile(PyObject *self, PyObject *args)
10255{
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 PyObject *ofilepath;
10257 char *filepath;
10258 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010259 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010261
Victor Stinnereb5657a2011-09-30 01:44:27 +020010262 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 if (!PyArg_ParseTuple(args, "U|s:startfile",
10264 &unipath, &operation)) {
10265 PyErr_Clear();
10266 goto normal;
10267 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010268
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010270 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010272 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 PyErr_Clear();
10274 operation = NULL;
10275 goto normal;
10276 }
10277 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010278
Victor Stinnereb5657a2011-09-30 01:44:27 +020010279 wpath = PyUnicode_AsUnicode(unipath);
10280 if (wpath == NULL)
10281 goto normal;
10282 if (uoperation) {
10283 woperation = PyUnicode_AsUnicode(uoperation);
10284 if (woperation == NULL)
10285 goto normal;
10286 }
10287 else
10288 woperation = NULL;
10289
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010291 rc = ShellExecuteW((HWND)0, woperation, wpath,
10292 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 Py_END_ALLOW_THREADS
10294
Victor Stinnereb5657a2011-09-30 01:44:27 +020010295 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010297 win32_error_object("startfile", unipath);
10298 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 }
10300 Py_INCREF(Py_None);
10301 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010302
10303normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10305 PyUnicode_FSConverter, &ofilepath,
10306 &operation))
10307 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010308 if (win32_warn_bytes_api()) {
10309 Py_DECREF(ofilepath);
10310 return NULL;
10311 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 filepath = PyBytes_AsString(ofilepath);
10313 Py_BEGIN_ALLOW_THREADS
10314 rc = ShellExecute((HWND)0, operation, filepath,
10315 NULL, NULL, SW_SHOWNORMAL);
10316 Py_END_ALLOW_THREADS
10317 if (rc <= (HINSTANCE)32) {
10318 PyObject *errval = win32_error("startfile", filepath);
10319 Py_DECREF(ofilepath);
10320 return errval;
10321 }
10322 Py_DECREF(ofilepath);
10323 Py_INCREF(Py_None);
10324 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010325}
10326#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010327
Martin v. Löwis438b5342002-12-27 10:16:42 +000010328#ifdef HAVE_GETLOADAVG
10329PyDoc_STRVAR(posix_getloadavg__doc__,
10330"getloadavg() -> (float, float, float)\n\n\
10331Return the number of processes in the system run queue averaged over\n\
10332the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10333was unobtainable");
10334
10335static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010336posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010337{
10338 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010339 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010340 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10341 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010342 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010343 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010344}
10345#endif
10346
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010347PyDoc_STRVAR(device_encoding__doc__,
10348"device_encoding(fd) -> str\n\n\
10349Return a string describing the encoding of the device\n\
10350if the output is a terminal; else return None.");
10351
10352static PyObject *
10353device_encoding(PyObject *self, PyObject *args)
10354{
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010356
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10358 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010359
10360 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010361}
10362
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010363#ifdef HAVE_SETRESUID
10364PyDoc_STRVAR(posix_setresuid__doc__,
10365"setresuid(ruid, euid, suid)\n\n\
10366Set the current process's real, effective, and saved user ids.");
10367
10368static PyObject*
10369posix_setresuid (PyObject *self, PyObject *args)
10370{
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 /* We assume uid_t is no larger than a long. */
10372 long ruid, euid, suid;
10373 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
10374 return NULL;
10375 if (setresuid(ruid, euid, suid) < 0)
10376 return posix_error();
10377 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010378}
10379#endif
10380
10381#ifdef HAVE_SETRESGID
10382PyDoc_STRVAR(posix_setresgid__doc__,
10383"setresgid(rgid, egid, sgid)\n\n\
10384Set the current process's real, effective, and saved group ids.");
10385
10386static PyObject*
10387posix_setresgid (PyObject *self, PyObject *args)
10388{
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 /* We assume uid_t is no larger than a long. */
10390 long rgid, egid, sgid;
10391 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
10392 return NULL;
10393 if (setresgid(rgid, egid, sgid) < 0)
10394 return posix_error();
10395 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010396}
10397#endif
10398
10399#ifdef HAVE_GETRESUID
10400PyDoc_STRVAR(posix_getresuid__doc__,
10401"getresuid() -> (ruid, euid, suid)\n\n\
10402Get tuple of the current process's real, effective, and saved user ids.");
10403
10404static PyObject*
10405posix_getresuid (PyObject *self, PyObject *noargs)
10406{
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 uid_t ruid, euid, suid;
10408 long l_ruid, l_euid, l_suid;
10409 if (getresuid(&ruid, &euid, &suid) < 0)
10410 return posix_error();
10411 /* Force the values into long's as we don't know the size of uid_t. */
10412 l_ruid = ruid;
10413 l_euid = euid;
10414 l_suid = suid;
10415 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010416}
10417#endif
10418
10419#ifdef HAVE_GETRESGID
10420PyDoc_STRVAR(posix_getresgid__doc__,
10421"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010422Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010423
10424static PyObject*
10425posix_getresgid (PyObject *self, PyObject *noargs)
10426{
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 uid_t rgid, egid, sgid;
10428 long l_rgid, l_egid, l_sgid;
10429 if (getresgid(&rgid, &egid, &sgid) < 0)
10430 return posix_error();
10431 /* Force the values into long's as we don't know the size of uid_t. */
10432 l_rgid = rgid;
10433 l_egid = egid;
10434 l_sgid = sgid;
10435 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010436}
10437#endif
10438
Benjamin Peterson9428d532011-09-14 11:45:52 -040010439#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010440
Benjamin Peterson799bd802011-08-31 22:15:17 -040010441PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010442"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10443Return the value of extended attribute attribute on path.\n\
10444\n\
10445path may be either a string or an open file descriptor.\n\
10446If follow_symlinks is False, and the last element of the path is a symbolic\n\
10447 link, getxattr will examine the symbolic link itself instead of the file\n\
10448 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010449
10450static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010451posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010452{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010453 path_t path;
10454 path_t attribute;
10455 int follow_symlinks = 1;
10456 PyObject *buffer = NULL;
10457 int i;
10458 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010459
Larry Hastings9cf065c2012-06-22 16:30:09 -070010460 memset(&path, 0, sizeof(path));
10461 memset(&attribute, 0, sizeof(attribute));
10462 path.allow_fd = 1;
10463 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10464 path_converter, &path,
10465 path_converter, &attribute,
10466 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010467 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010468
Larry Hastings9cf065c2012-06-22 16:30:09 -070010469 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10470 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010471
Larry Hastings9cf065c2012-06-22 16:30:09 -070010472 for (i = 0; ; i++) {
10473 void *ptr;
10474 ssize_t result;
10475 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10476 Py_ssize_t buffer_size = buffer_sizes[i];
10477 if (!buffer_size) {
10478 path_error("getxattr", &path);
10479 goto exit;
10480 }
10481 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10482 if (!buffer)
10483 goto exit;
10484 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010485
Larry Hastings9cf065c2012-06-22 16:30:09 -070010486 Py_BEGIN_ALLOW_THREADS;
10487 if (path.fd >= 0)
10488 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10489 else if (follow_symlinks)
10490 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10491 else
10492 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10493 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010494
Larry Hastings9cf065c2012-06-22 16:30:09 -070010495 if (result < 0) {
10496 Py_DECREF(buffer);
10497 buffer = NULL;
10498 if (errno == ERANGE)
10499 continue;
10500 path_error("getxattr", &path);
10501 goto exit;
10502 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010503
Larry Hastings9cf065c2012-06-22 16:30:09 -070010504 if (result != buffer_size) {
10505 /* Can only shrink. */
10506 _PyBytes_Resize(&buffer, result);
10507 }
10508 break;
10509 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010510
Larry Hastings9cf065c2012-06-22 16:30:09 -070010511exit:
10512 path_cleanup(&path);
10513 path_cleanup(&attribute);
10514 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010515}
10516
10517PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010518"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10519Set extended attribute attribute on path to value.\n\
10520path may be either a string or an open file descriptor.\n\
10521If follow_symlinks is False, and the last element of the path is a symbolic\n\
10522 link, setxattr will modify the symbolic link itself instead of the file\n\
10523 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010524
10525static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010526posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010527{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010528 path_t path;
10529 path_t attribute;
10530 Py_buffer value;
10531 int flags = 0;
10532 int follow_symlinks = 1;
10533 int result;
10534 PyObject *return_value = NULL;
10535 static char *keywords[] = {"path", "attribute", "value",
10536 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010537
Larry Hastings9cf065c2012-06-22 16:30:09 -070010538 memset(&path, 0, sizeof(path));
10539 path.allow_fd = 1;
10540 memset(&attribute, 0, sizeof(attribute));
10541 memset(&value, 0, sizeof(value));
10542 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10543 keywords,
10544 path_converter, &path,
10545 path_converter, &attribute,
10546 &value, &flags,
10547 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010548 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010549
10550 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10551 goto exit;
10552
Benjamin Peterson799bd802011-08-31 22:15:17 -040010553 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010554 if (path.fd > -1)
10555 result = fsetxattr(path.fd, attribute.narrow,
10556 value.buf, value.len, flags);
10557 else if (follow_symlinks)
10558 result = setxattr(path.narrow, attribute.narrow,
10559 value.buf, value.len, flags);
10560 else
10561 result = lsetxattr(path.narrow, attribute.narrow,
10562 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010563 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010564
Larry Hastings9cf065c2012-06-22 16:30:09 -070010565 if (result) {
10566 return_value = path_error("setxattr", &path);
10567 goto exit;
10568 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010569
Larry Hastings9cf065c2012-06-22 16:30:09 -070010570 return_value = Py_None;
10571 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010572
Larry Hastings9cf065c2012-06-22 16:30:09 -070010573exit:
10574 path_cleanup(&path);
10575 path_cleanup(&attribute);
10576 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010577
Larry Hastings9cf065c2012-06-22 16:30:09 -070010578 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010579}
10580
10581PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010582"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10583Remove extended attribute attribute on path.\n\
10584path may be either a string or an open file descriptor.\n\
10585If follow_symlinks is False, and the last element of the path is a symbolic\n\
10586 link, removexattr will modify the symbolic link itself instead of the file\n\
10587 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010588
10589static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010590posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010591{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010592 path_t path;
10593 path_t attribute;
10594 int follow_symlinks = 1;
10595 int result;
10596 PyObject *return_value = NULL;
10597 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010598
Larry Hastings9cf065c2012-06-22 16:30:09 -070010599 memset(&path, 0, sizeof(path));
10600 memset(&attribute, 0, sizeof(attribute));
10601 path.allow_fd = 1;
10602 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10603 keywords,
10604 path_converter, &path,
10605 path_converter, &attribute,
10606 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010607 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010608
10609 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10610 goto exit;
10611
Benjamin Peterson799bd802011-08-31 22:15:17 -040010612 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010613 if (path.fd > -1)
10614 result = fremovexattr(path.fd, attribute.narrow);
10615 else if (follow_symlinks)
10616 result = removexattr(path.narrow, attribute.narrow);
10617 else
10618 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010619 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010620
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621 if (result) {
10622 return_value = path_error("removexattr", &path);
10623 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010624 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010625
Larry Hastings9cf065c2012-06-22 16:30:09 -070010626 return_value = Py_None;
10627 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010628
Larry Hastings9cf065c2012-06-22 16:30:09 -070010629exit:
10630 path_cleanup(&path);
10631 path_cleanup(&attribute);
10632
10633 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010634}
10635
10636PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010637"listxattr(path='.', *, follow_symlinks=True)\n\n\
10638Return a list of extended attributes on path.\n\
10639\n\
10640path may be either None, a string, or an open file descriptor.\n\
10641if path is None, listxattr will examine the current directory.\n\
10642If follow_symlinks is False, and the last element of the path is a symbolic\n\
10643 link, listxattr will examine the symbolic link itself instead of the file\n\
10644 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010645
10646static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010647posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010648{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010649 path_t path;
10650 int follow_symlinks = 1;
10651 Py_ssize_t i;
10652 PyObject *result = NULL;
10653 char *buffer = NULL;
10654 char *name;
10655 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656
Larry Hastings9cf065c2012-06-22 16:30:09 -070010657 memset(&path, 0, sizeof(path));
10658 path.allow_fd = 1;
10659 path.fd = -1;
10660 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10661 path_converter, &path,
10662 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010663 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010664
Larry Hastings9cf065c2012-06-22 16:30:09 -070010665 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10666 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010667
Larry Hastings9cf065c2012-06-22 16:30:09 -070010668 name = path.narrow ? path.narrow : ".";
10669 for (i = 0; ; i++) {
10670 char *start, *trace, *end;
10671 ssize_t length;
10672 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10673 Py_ssize_t buffer_size = buffer_sizes[i];
10674 if (!buffer_size) {
10675 // ERANGE
10676 path_error("listxattr", &path);
10677 break;
10678 }
10679 buffer = PyMem_MALLOC(buffer_size);
10680 if (!buffer) {
10681 PyErr_NoMemory();
10682 break;
10683 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010684
Larry Hastings9cf065c2012-06-22 16:30:09 -070010685 Py_BEGIN_ALLOW_THREADS;
10686 if (path.fd > -1)
10687 length = flistxattr(path.fd, buffer, buffer_size);
10688 else if (follow_symlinks)
10689 length = listxattr(name, buffer, buffer_size);
10690 else
10691 length = llistxattr(name, buffer, buffer_size);
10692 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010693
Larry Hastings9cf065c2012-06-22 16:30:09 -070010694 if (length < 0) {
10695 if (errno == ERANGE)
10696 continue;
10697 path_error("listxattr", &path);
10698 break;
10699 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010700
Larry Hastings9cf065c2012-06-22 16:30:09 -070010701 result = PyList_New(0);
10702 if (!result) {
10703 goto exit;
10704 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010705
Larry Hastings9cf065c2012-06-22 16:30:09 -070010706 end = buffer + length;
10707 for (trace = start = buffer; trace != end; trace++) {
10708 if (!*trace) {
10709 int error;
10710 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10711 trace - start);
10712 if (!attribute) {
10713 Py_DECREF(result);
10714 result = NULL;
10715 goto exit;
10716 }
10717 error = PyList_Append(result, attribute);
10718 Py_DECREF(attribute);
10719 if (error) {
10720 Py_DECREF(result);
10721 result = NULL;
10722 goto exit;
10723 }
10724 start = trace + 1;
10725 }
10726 }
10727 break;
10728 }
10729exit:
10730 path_cleanup(&path);
10731 if (buffer)
10732 PyMem_FREE(buffer);
10733 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010734}
10735
Benjamin Peterson9428d532011-09-14 11:45:52 -040010736#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010737
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010738
Georg Brandl2fb477c2012-02-21 00:33:36 +010010739PyDoc_STRVAR(posix_urandom__doc__,
10740"urandom(n) -> str\n\n\
10741Return n random bytes suitable for cryptographic use.");
10742
10743static PyObject *
10744posix_urandom(PyObject *self, PyObject *args)
10745{
10746 Py_ssize_t size;
10747 PyObject *result;
10748 int ret;
10749
10750 /* Read arguments */
10751 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10752 return NULL;
10753 if (size < 0)
10754 return PyErr_Format(PyExc_ValueError,
10755 "negative argument not allowed");
10756 result = PyBytes_FromStringAndSize(NULL, size);
10757 if (result == NULL)
10758 return NULL;
10759
10760 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10761 PyBytes_GET_SIZE(result));
10762 if (ret == -1) {
10763 Py_DECREF(result);
10764 return NULL;
10765 }
10766 return result;
10767}
10768
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010769/* Terminal size querying */
10770
10771static PyTypeObject TerminalSizeType;
10772
10773PyDoc_STRVAR(TerminalSize_docstring,
10774 "A tuple of (columns, lines) for holding terminal window size");
10775
10776static PyStructSequence_Field TerminalSize_fields[] = {
10777 {"columns", "width of the terminal window in characters"},
10778 {"lines", "height of the terminal window in characters"},
10779 {NULL, NULL}
10780};
10781
10782static PyStructSequence_Desc TerminalSize_desc = {
10783 "os.terminal_size",
10784 TerminalSize_docstring,
10785 TerminalSize_fields,
10786 2,
10787};
10788
10789#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10790PyDoc_STRVAR(termsize__doc__,
10791 "Return the size of the terminal window as (columns, lines).\n" \
10792 "\n" \
10793 "The optional argument fd (default standard output) specifies\n" \
10794 "which file descriptor should be queried.\n" \
10795 "\n" \
10796 "If the file descriptor is not connected to a terminal, an OSError\n" \
10797 "is thrown.\n" \
10798 "\n" \
10799 "This function will only be defined if an implementation is\n" \
10800 "available for this system.\n" \
10801 "\n" \
10802 "shutil.get_terminal_size is the high-level function which should \n" \
10803 "normally be used, os.get_terminal_size is the low-level implementation.");
10804
10805static PyObject*
10806get_terminal_size(PyObject *self, PyObject *args)
10807{
10808 int columns, lines;
10809 PyObject *termsize;
10810
10811 int fd = fileno(stdout);
10812 /* Under some conditions stdout may not be connected and
10813 * fileno(stdout) may point to an invalid file descriptor. For example
10814 * GUI apps don't have valid standard streams by default.
10815 *
10816 * If this happens, and the optional fd argument is not present,
10817 * the ioctl below will fail returning EBADF. This is what we want.
10818 */
10819
10820 if (!PyArg_ParseTuple(args, "|i", &fd))
10821 return NULL;
10822
10823#ifdef TERMSIZE_USE_IOCTL
10824 {
10825 struct winsize w;
10826 if (ioctl(fd, TIOCGWINSZ, &w))
10827 return PyErr_SetFromErrno(PyExc_OSError);
10828 columns = w.ws_col;
10829 lines = w.ws_row;
10830 }
10831#endif /* TERMSIZE_USE_IOCTL */
10832
10833#ifdef TERMSIZE_USE_CONIO
10834 {
10835 DWORD nhandle;
10836 HANDLE handle;
10837 CONSOLE_SCREEN_BUFFER_INFO csbi;
10838 switch (fd) {
10839 case 0: nhandle = STD_INPUT_HANDLE;
10840 break;
10841 case 1: nhandle = STD_OUTPUT_HANDLE;
10842 break;
10843 case 2: nhandle = STD_ERROR_HANDLE;
10844 break;
10845 default:
10846 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10847 }
10848 handle = GetStdHandle(nhandle);
10849 if (handle == NULL)
10850 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10851 if (handle == INVALID_HANDLE_VALUE)
10852 return PyErr_SetFromWindowsErr(0);
10853
10854 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10855 return PyErr_SetFromWindowsErr(0);
10856
10857 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10858 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10859 }
10860#endif /* TERMSIZE_USE_CONIO */
10861
10862 termsize = PyStructSequence_New(&TerminalSizeType);
10863 if (termsize == NULL)
10864 return NULL;
10865 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10866 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10867 if (PyErr_Occurred()) {
10868 Py_DECREF(termsize);
10869 return NULL;
10870 }
10871 return termsize;
10872}
10873#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10874
10875
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010876static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010877 {"access", (PyCFunction)posix_access,
10878 METH_VARARGS | METH_KEYWORDS,
10879 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010880#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010882#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010883 {"chdir", (PyCFunction)posix_chdir,
10884 METH_VARARGS | METH_KEYWORDS,
10885 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010886#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010887 {"chflags", (PyCFunction)posix_chflags,
10888 METH_VARARGS | METH_KEYWORDS,
10889 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010890#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010891 {"chmod", (PyCFunction)posix_chmod,
10892 METH_VARARGS | METH_KEYWORDS,
10893 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010894#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010896#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010897#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010898 {"chown", (PyCFunction)posix_chown,
10899 METH_VARARGS | METH_KEYWORDS,
10900 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010901#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010902#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010903 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010904#endif /* HAVE_LCHMOD */
10905#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010906 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010907#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010908#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010910#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010911#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010913#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010914#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010916#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010917#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010919#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010920#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10922 METH_NOARGS, posix_getcwd__doc__},
10923 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10924 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010925#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010926#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10927 {"link", (PyCFunction)posix_link,
10928 METH_VARARGS | METH_KEYWORDS,
10929 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010930#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010931 {"listdir", (PyCFunction)posix_listdir,
10932 METH_VARARGS | METH_KEYWORDS,
10933 posix_listdir__doc__},
10934 {"lstat", (PyCFunction)posix_lstat,
10935 METH_VARARGS | METH_KEYWORDS,
10936 posix_lstat__doc__},
10937 {"mkdir", (PyCFunction)posix_mkdir,
10938 METH_VARARGS | METH_KEYWORDS,
10939 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010940#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010942#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010943#ifdef HAVE_GETPRIORITY
10944 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10945#endif /* HAVE_GETPRIORITY */
10946#ifdef HAVE_SETPRIORITY
10947 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10948#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010949#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010950 {"readlink", (PyCFunction)posix_readlink,
10951 METH_VARARGS | METH_KEYWORDS,
10952 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010953#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010954#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010955 {"readlink", (PyCFunction)win_readlink,
10956 METH_VARARGS | METH_KEYWORDS,
10957 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010958#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010959 {"rename", (PyCFunction)posix_rename,
10960 METH_VARARGS | METH_KEYWORDS,
10961 posix_rename__doc__},
10962 {"replace", (PyCFunction)posix_replace,
10963 METH_VARARGS | METH_KEYWORDS,
10964 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010965 {"rmdir", (PyCFunction)posix_rmdir,
10966 METH_VARARGS | METH_KEYWORDS,
10967 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010968 {"stat", (PyCFunction)posix_stat,
10969 METH_VARARGS | METH_KEYWORDS,
10970 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010971 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010972#if defined(HAVE_SYMLINK)
10973 {"symlink", (PyCFunction)posix_symlink,
10974 METH_VARARGS | METH_KEYWORDS,
10975 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010976#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010977#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010979#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010981#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010983#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010984 {"unlink", (PyCFunction)posix_unlink,
10985 METH_VARARGS | METH_KEYWORDS,
10986 posix_unlink__doc__},
10987 {"remove", (PyCFunction)posix_unlink,
10988 METH_VARARGS | METH_KEYWORDS,
10989 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010990 {"utime", (PyCFunction)posix_utime,
10991 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010992#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010993 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010994#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010996#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010997 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010998 {"execve", (PyCFunction)posix_execve,
10999 METH_VARARGS | METH_KEYWORDS,
11000 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011001#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011002#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011003 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11004 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000011005#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011006 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
11007 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000011008#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000011009#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011010#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011012#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011013#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011015#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011016#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011017#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011018 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11019 {"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 +020011020#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011021#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011022 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011023#endif
11024#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011025 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011026#endif
11027#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011028 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011029#endif
11030#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011031 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011032#endif
11033#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011034 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011035#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011036 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011037#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011038 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11039 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11040#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011041#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011042#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011044#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011045#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011047#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011048#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011049 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011050#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011051#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011052 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011053#endif /* HAVE_GETEUID */
11054#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011055 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011056#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011057#ifdef HAVE_GETGROUPLIST
11058 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11059#endif
Fred Drakec9680921999-12-13 16:37:25 +000011060#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011061 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011062#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011063 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011064#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011066#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011067#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011069#endif /* HAVE_GETPPID */
11070#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011072#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011073#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011075#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011076#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011078#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011079#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011081#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011082#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011084#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011085#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011086 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11087 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011088#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011089#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011091#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011092#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011094#endif /* HAVE_SETEUID */
11095#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011097#endif /* HAVE_SETEGID */
11098#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011100#endif /* HAVE_SETREUID */
11101#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011103#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011104#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011105 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011106#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011107#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011108 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011109#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011110#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011111 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011112#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011113#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011114 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011115#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011116#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011117 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011118#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011119#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011121#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011122#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011123 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011124#endif /* HAVE_WAIT3 */
11125#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011126 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011127#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011128#if defined(HAVE_WAITID) && !defined(__APPLE__)
11129 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11130#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011131#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011133#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011134#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011136#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011137#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011139#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011140#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011141 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011142#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011143#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011145#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011146#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011148#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011149 {"open", (PyCFunction)posix_open,\
11150 METH_VARARGS | METH_KEYWORDS,
11151 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11153 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11154 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11155 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11156 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011157#ifdef HAVE_LOCKF
11158 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11159#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11161 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011162#ifdef HAVE_READV
11163 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11164#endif
11165#ifdef HAVE_PREAD
11166 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11167#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011168 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011169#ifdef HAVE_WRITEV
11170 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11171#endif
11172#ifdef HAVE_PWRITE
11173 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11174#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011175#ifdef HAVE_SENDFILE
11176 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11177 posix_sendfile__doc__},
11178#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011179 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011180 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011181#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011183#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011184#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011185 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011186#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011187#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011188 {"mkfifo", (PyCFunction)posix_mkfifo,
11189 METH_VARARGS | METH_KEYWORDS,
11190 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011191#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011192#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011193 {"mknod", (PyCFunction)posix_mknod,
11194 METH_VARARGS | METH_KEYWORDS,
11195 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011196#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011197#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011198 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11199 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11200 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011201#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011202#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011204#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011205#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011206 {"truncate", (PyCFunction)posix_truncate,
11207 METH_VARARGS | METH_KEYWORDS,
11208 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011209#endif
11210#ifdef HAVE_POSIX_FALLOCATE
11211 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11212#endif
11213#ifdef HAVE_POSIX_FADVISE
11214 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11215#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011216#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011218#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011219#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011221#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011222 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011223#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011225#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011226#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011228#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011229#ifdef HAVE_SYNC
11230 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11231#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011232#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011234#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011235#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011236#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011237 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011238#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011239#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011240 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011241#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011242#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011244#endif /* WIFSTOPPED */
11245#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011246 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011247#endif /* WIFSIGNALED */
11248#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011249 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011250#endif /* WIFEXITED */
11251#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011252 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011253#endif /* WEXITSTATUS */
11254#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011256#endif /* WTERMSIG */
11257#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011259#endif /* WSTOPSIG */
11260#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011261#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011262 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011263#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011264#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011265 {"statvfs", (PyCFunction)posix_statvfs,
11266 METH_VARARGS | METH_KEYWORDS,
11267 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011268#endif
Fred Drakec9680921999-12-13 16:37:25 +000011269#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011270 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011271#endif
11272#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011273 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011274#endif
11275#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011276 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011277#endif
11278#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011279 {"pathconf", (PyCFunction)posix_pathconf,
11280 METH_VARARGS | METH_KEYWORDS,
11281 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011282#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011284#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011286 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011287 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011288 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011289 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011290#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011291#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011293#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011294 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011295#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011296 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011297#endif
11298#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011299 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011300#endif
11301#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011302 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011303#endif
11304#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011305 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011306#endif
11307
Benjamin Peterson9428d532011-09-14 11:45:52 -040011308#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011309 {"setxattr", (PyCFunction)posix_setxattr,
11310 METH_VARARGS | METH_KEYWORDS,
11311 posix_setxattr__doc__},
11312 {"getxattr", (PyCFunction)posix_getxattr,
11313 METH_VARARGS | METH_KEYWORDS,
11314 posix_getxattr__doc__},
11315 {"removexattr", (PyCFunction)posix_removexattr,
11316 METH_VARARGS | METH_KEYWORDS,
11317 posix_removexattr__doc__},
11318 {"listxattr", (PyCFunction)posix_listxattr,
11319 METH_VARARGS | METH_KEYWORDS,
11320 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011321#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011322#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11323 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11324#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011325 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011326};
11327
11328
Barry Warsaw4a342091996-12-19 23:50:02 +000011329static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011330ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011331{
Victor Stinner8c62be82010-05-06 00:08:46 +000011332 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011333}
11334
Guido van Rossumd48f2521997-12-05 22:19:34 +000011335#if defined(PYOS_OS2)
11336/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011337static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011338{
11339 APIRET rc;
11340 ULONG values[QSV_MAX+1];
11341 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011342 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011343
11344 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011345 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011346 Py_END_ALLOW_THREADS
11347
11348 if (rc != NO_ERROR) {
11349 os2_error(rc);
11350 return -1;
11351 }
11352
Fred Drake4d1e64b2002-04-15 19:40:07 +000011353 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11354 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11355 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11356 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11357 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11358 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11359 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011360
11361 switch (values[QSV_VERSION_MINOR]) {
11362 case 0: ver = "2.00"; break;
11363 case 10: ver = "2.10"; break;
11364 case 11: ver = "2.11"; break;
11365 case 30: ver = "3.00"; break;
11366 case 40: ver = "4.00"; break;
11367 case 50: ver = "5.00"; break;
11368 default:
Tim Peters885d4572001-11-28 20:27:42 +000011369 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011370 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011371 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011372 ver = &tmp[0];
11373 }
11374
11375 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011376 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011377 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011378
11379 /* Add Indicator of Which Drive was Used to Boot the System */
11380 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11381 tmp[1] = ':';
11382 tmp[2] = '\0';
11383
Fred Drake4d1e64b2002-04-15 19:40:07 +000011384 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011385}
11386#endif
11387
Brian Curtin52173d42010-12-02 18:29:18 +000011388#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011389static int
Brian Curtin52173d42010-12-02 18:29:18 +000011390enable_symlink()
11391{
11392 HANDLE tok;
11393 TOKEN_PRIVILEGES tok_priv;
11394 LUID luid;
11395 int meth_idx = 0;
11396
11397 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011398 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011399
11400 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011401 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011402
11403 tok_priv.PrivilegeCount = 1;
11404 tok_priv.Privileges[0].Luid = luid;
11405 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11406
11407 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11408 sizeof(TOKEN_PRIVILEGES),
11409 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011410 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011411
Brian Curtin3b4499c2010-12-28 14:31:47 +000011412 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11413 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011414}
11415#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11416
Barry Warsaw4a342091996-12-19 23:50:02 +000011417static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011418all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011419{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011420#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011421 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011422#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011423#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011425#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011426#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011427 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011428#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011429#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011430 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011431#endif
Fred Drakec9680921999-12-13 16:37:25 +000011432#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011433 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011434#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011435#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011436 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011437#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011438#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011440#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011441#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011442 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011443#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011444#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011445 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011446#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011447#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011448 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011449#endif
11450#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011451 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011452#endif
11453#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011455#endif
11456#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011457 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011458#endif
11459#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011460 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011461#endif
11462#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011464#endif
11465#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011467#endif
11468#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011469 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011470#endif
11471#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011473#endif
11474#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011476#endif
11477#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011478 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011479#endif
11480#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011482#endif
11483#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011485#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011486#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011487 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011488#endif
11489#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011490 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011491#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011492#ifdef O_XATTR
11493 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11494#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011495#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011496 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011497#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011498#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011499 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011500#endif
11501#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011502 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011503#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011504#ifdef O_EXEC
11505 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11506#endif
11507#ifdef O_SEARCH
11508 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11509#endif
11510#ifdef O_TTY_INIT
11511 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11512#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011513#ifdef PRIO_PROCESS
11514 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11515#endif
11516#ifdef PRIO_PGRP
11517 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11518#endif
11519#ifdef PRIO_USER
11520 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11521#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011522#ifdef O_CLOEXEC
11523 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11524#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011525#ifdef O_ACCMODE
11526 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11527#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011528
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011529
Jesus Cea94363612012-06-22 18:32:07 +020011530#ifdef SEEK_HOLE
11531 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11532#endif
11533#ifdef SEEK_DATA
11534 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11535#endif
11536
Tim Peters5aa91602002-01-30 05:46:57 +000011537/* MS Windows */
11538#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 /* Don't inherit in child processes. */
11540 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011541#endif
11542#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 /* Optimize for short life (keep in memory). */
11544 /* MS forgot to define this one with a non-underscore form too. */
11545 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011546#endif
11547#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 /* Automatically delete when last handle is closed. */
11549 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011550#endif
11551#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 /* Optimize for random access. */
11553 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011554#endif
11555#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 /* Optimize for sequential access. */
11557 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011558#endif
11559
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011560/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011561#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011562 /* Send a SIGIO signal whenever input or output
11563 becomes available on file descriptor */
11564 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011565#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011566#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 /* Direct disk access. */
11568 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011569#endif
11570#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011571 /* Must be a directory. */
11572 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011573#endif
11574#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011575 /* Do not follow links. */
11576 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011577#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011578#ifdef O_NOLINKS
11579 /* Fails if link count of the named file is greater than 1 */
11580 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11581#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011582#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011583 /* Do not update the access time. */
11584 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011585#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011586
Victor Stinner8c62be82010-05-06 00:08:46 +000011587 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011588#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011589 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011590#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011591#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011592 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011593#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011594#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011595 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011596#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011597#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011598 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011599#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011600#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011601 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011602#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011603#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011605#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011606#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011607 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011608#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011609#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011611#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011612#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011614#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011615#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011616 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011617#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011618#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011619 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011620#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011621#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011622 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011623#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011624#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011625 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011626#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011627#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011629#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011630#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011631 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011632#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011633#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011634 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011635#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011636#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011637 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011638#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011639
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011640 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011641#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011642 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011643#endif /* ST_RDONLY */
11644#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011645 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011646#endif /* ST_NOSUID */
11647
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011648 /* FreeBSD sendfile() constants */
11649#ifdef SF_NODISKIO
11650 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11651#endif
11652#ifdef SF_MNOWAIT
11653 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11654#endif
11655#ifdef SF_SYNC
11656 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11657#endif
11658
Ross Lagerwall7807c352011-03-17 20:20:30 +020011659 /* constants for posix_fadvise */
11660#ifdef POSIX_FADV_NORMAL
11661 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11662#endif
11663#ifdef POSIX_FADV_SEQUENTIAL
11664 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11665#endif
11666#ifdef POSIX_FADV_RANDOM
11667 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11668#endif
11669#ifdef POSIX_FADV_NOREUSE
11670 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11671#endif
11672#ifdef POSIX_FADV_WILLNEED
11673 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11674#endif
11675#ifdef POSIX_FADV_DONTNEED
11676 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11677#endif
11678
11679 /* constants for waitid */
11680#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11681 if (ins(d, "P_PID", (long)P_PID)) return -1;
11682 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11683 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11684#endif
11685#ifdef WEXITED
11686 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11687#endif
11688#ifdef WNOWAIT
11689 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11690#endif
11691#ifdef WSTOPPED
11692 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11693#endif
11694#ifdef CLD_EXITED
11695 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11696#endif
11697#ifdef CLD_DUMPED
11698 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11699#endif
11700#ifdef CLD_TRAPPED
11701 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11702#endif
11703#ifdef CLD_CONTINUED
11704 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11705#endif
11706
11707 /* constants for lockf */
11708#ifdef F_LOCK
11709 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11710#endif
11711#ifdef F_TLOCK
11712 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11713#endif
11714#ifdef F_ULOCK
11715 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11716#endif
11717#ifdef F_TEST
11718 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11719#endif
11720
Guido van Rossum246bc171999-02-01 23:54:31 +000011721#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011722#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011723 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11724 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11725 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11726 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11727 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11728 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11729 if (ins(d, "P_PM", (long)P_PM)) return -1;
11730 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11731 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11732 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11733 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11734 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11735 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11736 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11737 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11738 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11739 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11740 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11741 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11742 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011743#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011744 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11745 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11746 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11747 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11748 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011749#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011750#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011751
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011752#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011753 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011754 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11755 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11756#ifdef SCHED_SPORADIC
11757 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11758#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011759#ifdef SCHED_BATCH
11760 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11761#endif
11762#ifdef SCHED_IDLE
11763 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11764#endif
11765#ifdef SCHED_RESET_ON_FORK
11766 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11767#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011768#ifdef SCHED_SYS
11769 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11770#endif
11771#ifdef SCHED_IA
11772 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11773#endif
11774#ifdef SCHED_FSS
11775 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11776#endif
11777#ifdef SCHED_FX
11778 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11779#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011780#endif
11781
Benjamin Peterson9428d532011-09-14 11:45:52 -040011782#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011783 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11784 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11785 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11786#endif
11787
Victor Stinner8b905bd2011-10-25 13:34:04 +020011788#ifdef RTLD_LAZY
11789 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11790#endif
11791#ifdef RTLD_NOW
11792 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11793#endif
11794#ifdef RTLD_GLOBAL
11795 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11796#endif
11797#ifdef RTLD_LOCAL
11798 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11799#endif
11800#ifdef RTLD_NODELETE
11801 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11802#endif
11803#ifdef RTLD_NOLOAD
11804 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11805#endif
11806#ifdef RTLD_DEEPBIND
11807 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11808#endif
11809
Guido van Rossumd48f2521997-12-05 22:19:34 +000011810#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011811 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011812#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011813 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011814}
11815
11816
Tim Peters5aa91602002-01-30 05:46:57 +000011817#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011818#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011819#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011820
11821#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011822#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011823#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011824
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011825#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011826#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011827#define MODNAME "posix"
11828#endif
11829
Martin v. Löwis1a214512008-06-11 05:26:20 +000011830static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011831 PyModuleDef_HEAD_INIT,
11832 MODNAME,
11833 posix__doc__,
11834 -1,
11835 posix_methods,
11836 NULL,
11837 NULL,
11838 NULL,
11839 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011840};
11841
11842
Larry Hastings9cf065c2012-06-22 16:30:09 -070011843static char *have_functions[] = {
11844
11845#ifdef HAVE_FACCESSAT
11846 "HAVE_FACCESSAT",
11847#endif
11848
11849#ifdef HAVE_FCHDIR
11850 "HAVE_FCHDIR",
11851#endif
11852
11853#ifdef HAVE_FCHMOD
11854 "HAVE_FCHMOD",
11855#endif
11856
11857#ifdef HAVE_FCHMODAT
11858 "HAVE_FCHMODAT",
11859#endif
11860
11861#ifdef HAVE_FCHOWN
11862 "HAVE_FCHOWN",
11863#endif
11864
11865#ifdef HAVE_FEXECVE
11866 "HAVE_FEXECVE",
11867#endif
11868
11869#ifdef HAVE_FDOPENDIR
11870 "HAVE_FDOPENDIR",
11871#endif
11872
Georg Brandl306336b2012-06-24 12:55:33 +020011873#ifdef HAVE_FPATHCONF
11874 "HAVE_FPATHCONF",
11875#endif
11876
Larry Hastings9cf065c2012-06-22 16:30:09 -070011877#ifdef HAVE_FSTATAT
11878 "HAVE_FSTATAT",
11879#endif
11880
11881#ifdef HAVE_FSTATVFS
11882 "HAVE_FSTATVFS",
11883#endif
11884
Georg Brandl306336b2012-06-24 12:55:33 +020011885#ifdef HAVE_FTRUNCATE
11886 "HAVE_FTRUNCATE",
11887#endif
11888
Larry Hastings9cf065c2012-06-22 16:30:09 -070011889#ifdef HAVE_FUTIMENS
11890 "HAVE_FUTIMENS",
11891#endif
11892
11893#ifdef HAVE_FUTIMES
11894 "HAVE_FUTIMES",
11895#endif
11896
11897#ifdef HAVE_FUTIMESAT
11898 "HAVE_FUTIMESAT",
11899#endif
11900
11901#ifdef HAVE_LINKAT
11902 "HAVE_LINKAT",
11903#endif
11904
11905#ifdef HAVE_LCHFLAGS
11906 "HAVE_LCHFLAGS",
11907#endif
11908
11909#ifdef HAVE_LCHMOD
11910 "HAVE_LCHMOD",
11911#endif
11912
11913#ifdef HAVE_LCHOWN
11914 "HAVE_LCHOWN",
11915#endif
11916
11917#ifdef HAVE_LSTAT
11918 "HAVE_LSTAT",
11919#endif
11920
11921#ifdef HAVE_LUTIMES
11922 "HAVE_LUTIMES",
11923#endif
11924
11925#ifdef HAVE_MKDIRAT
11926 "HAVE_MKDIRAT",
11927#endif
11928
11929#ifdef HAVE_MKFIFOAT
11930 "HAVE_MKFIFOAT",
11931#endif
11932
11933#ifdef HAVE_MKNODAT
11934 "HAVE_MKNODAT",
11935#endif
11936
11937#ifdef HAVE_OPENAT
11938 "HAVE_OPENAT",
11939#endif
11940
11941#ifdef HAVE_READLINKAT
11942 "HAVE_READLINKAT",
11943#endif
11944
11945#ifdef HAVE_RENAMEAT
11946 "HAVE_RENAMEAT",
11947#endif
11948
11949#ifdef HAVE_SYMLINKAT
11950 "HAVE_SYMLINKAT",
11951#endif
11952
11953#ifdef HAVE_UNLINKAT
11954 "HAVE_UNLINKAT",
11955#endif
11956
11957#ifdef HAVE_UTIMENSAT
11958 "HAVE_UTIMENSAT",
11959#endif
11960
11961#ifdef MS_WINDOWS
11962 "MS_WINDOWS",
11963#endif
11964
11965 NULL
11966};
11967
11968
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011969PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011970INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011971{
Victor Stinner8c62be82010-05-06 00:08:46 +000011972 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011973 PyObject *list;
11974 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011975
Brian Curtin52173d42010-12-02 18:29:18 +000011976#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011977 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011978#endif
11979
Victor Stinner8c62be82010-05-06 00:08:46 +000011980 m = PyModule_Create(&posixmodule);
11981 if (m == NULL)
11982 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011983
Victor Stinner8c62be82010-05-06 00:08:46 +000011984 /* Initialize environ dictionary */
11985 v = convertenviron();
11986 Py_XINCREF(v);
11987 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11988 return NULL;
11989 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011990
Victor Stinner8c62be82010-05-06 00:08:46 +000011991 if (all_ins(m))
11992 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011993
Victor Stinner8c62be82010-05-06 00:08:46 +000011994 if (setup_confname_tables(m))
11995 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011996
Victor Stinner8c62be82010-05-06 00:08:46 +000011997 Py_INCREF(PyExc_OSError);
11998 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011999
Benjamin Peterson2740af82011-08-02 17:41:34 -050012000#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012001 if (PyType_Ready(&cpu_set_type) < 0)
12002 return NULL;
12003 Py_INCREF(&cpu_set_type);
12004 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050012005#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012006
Guido van Rossumb3d39562000-01-31 18:41:26 +000012007#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012008 if (posix_putenv_garbage == NULL)
12009 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012010#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012011
Victor Stinner8c62be82010-05-06 00:08:46 +000012012 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012013#if defined(HAVE_WAITID) && !defined(__APPLE__)
12014 waitid_result_desc.name = MODNAME ".waitid_result";
12015 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
12016#endif
12017
Victor Stinner8c62be82010-05-06 00:08:46 +000012018 stat_result_desc.name = MODNAME ".stat_result";
12019 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12020 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12021 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
12022 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
12023 structseq_new = StatResultType.tp_new;
12024 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012025
Victor Stinner8c62be82010-05-06 00:08:46 +000012026 statvfs_result_desc.name = MODNAME ".statvfs_result";
12027 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012028#ifdef NEED_TICKS_PER_SECOND
12029# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012030 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012031# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012032 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012033# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012034 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012035# endif
12036#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012037
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012038#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012039 sched_param_desc.name = MODNAME ".sched_param";
12040 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
12041 SchedParamType.tp_new = sched_param_new;
12042#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012043
12044 /* initialize TerminalSize_info */
12045 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
12046 Py_INCREF(&TerminalSizeType);
Victor Stinner8c62be82010-05-06 00:08:46 +000012047 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012048#if defined(HAVE_WAITID) && !defined(__APPLE__)
12049 Py_INCREF((PyObject*) &WaitidResultType);
12050 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12051#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012052 Py_INCREF((PyObject*) &StatResultType);
12053 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12054 Py_INCREF((PyObject*) &StatVFSResultType);
12055 PyModule_AddObject(m, "statvfs_result",
12056 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012057
12058#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012059 Py_INCREF(&SchedParamType);
12060 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012061#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012062
Larry Hastings605a62d2012-06-24 04:33:36 -070012063 times_result_desc.name = MODNAME ".times_result";
12064 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
12065 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12066
12067 uname_result_desc.name = MODNAME ".uname_result";
12068 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
12069 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12070
Thomas Wouters477c8d52006-05-27 19:21:47 +000012071#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012072 /*
12073 * Step 2 of weak-linking support on Mac OS X.
12074 *
12075 * The code below removes functions that are not available on the
12076 * currently active platform.
12077 *
12078 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012079 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012080 * OSX 10.4.
12081 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012082#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012083 if (fstatvfs == NULL) {
12084 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12085 return NULL;
12086 }
12087 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012088#endif /* HAVE_FSTATVFS */
12089
12090#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012091 if (statvfs == NULL) {
12092 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12093 return NULL;
12094 }
12095 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012096#endif /* HAVE_STATVFS */
12097
12098# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012099 if (lchown == NULL) {
12100 if (PyObject_DelAttrString(m, "lchown") == -1) {
12101 return NULL;
12102 }
12103 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012104#endif /* HAVE_LCHOWN */
12105
12106
12107#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012108
12109 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12110
Larry Hastings6fe20b32012-04-19 15:07:49 -070012111 billion = PyLong_FromLong(1000000000);
12112 if (!billion)
12113 return NULL;
12114
Larry Hastings9cf065c2012-06-22 16:30:09 -070012115 /* suppress "function not used" warnings */
12116 {
12117 int ignored;
12118 fd_specified("", -1);
12119 follow_symlinks_specified("", 1);
12120 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12121 dir_fd_converter(Py_None, &ignored);
12122 dir_fd_unavailable(Py_None, &ignored);
12123 }
12124
12125 /*
12126 * provide list of locally available functions
12127 * so os.py can populate support_* lists
12128 */
12129 list = PyList_New(0);
12130 if (!list)
12131 return NULL;
12132 for (trace = have_functions; *trace; trace++) {
12133 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12134 if (!unicode)
12135 return NULL;
12136 if (PyList_Append(list, unicode))
12137 return NULL;
12138 Py_DECREF(unicode);
12139 }
12140 PyModule_AddObject(m, "_have_functions", list);
12141
12142 initialized = 1;
12143
Victor Stinner8c62be82010-05-06 00:08:46 +000012144 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012145
Guido van Rossumb6775db1994-08-01 11:34:53 +000012146}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012147
12148#ifdef __cplusplus
12149}
12150#endif