blob: 7e36df5da6a283154f23ba113549c88fe5fce95e [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"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
31#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000032
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020034# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000036#endif /* defined(__VMS) */
37
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000038#ifdef __cplusplus
39extern "C" {
40#endif
41
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000042PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000043"This module provides access to operating system functionality that is\n\
44standardized by the C Standard and the POSIX standard (a thinly\n\
45disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000046corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000048
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000049#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020050#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#define INCL_DOS
52#define INCL_DOSERRORS
53#define INCL_DOSPROCESS
54#define INCL_NOPMAPI
55#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000056#if defined(PYCC_GCC)
57#include <ctype.h>
58#include <io.h>
59#include <stdio.h>
60#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000061#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000062#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000063#endif
64
Ross Lagerwall4d076da2011-03-18 06:56:53 +020065#ifdef HAVE_SYS_UIO_H
66#include <sys/uio.h>
67#endif
68
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000070#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000071#endif /* HAVE_SYS_TYPES_H */
72
73#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000076
Guido van Rossum36bc6801995-06-14 22:54:23 +000077#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000078#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000079#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000080
Thomas Wouters0e3f5912006-08-11 14:57:12 +000081#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000082#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000083#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000084
Guido van Rossumb6775db1994-08-01 11:34:53 +000085#ifdef HAVE_FCNTL_H
86#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000087#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000088
Guido van Rossuma6535fd2001-10-18 19:44:10 +000089#ifdef HAVE_GRP_H
90#include <grp.h>
91#endif
92
Barry Warsaw5676bd12003-01-07 20:57:09 +000093#ifdef HAVE_SYSEXITS_H
94#include <sysexits.h>
95#endif /* HAVE_SYSEXITS_H */
96
Anthony Baxter8a560de2004-10-13 15:30:56 +000097#ifdef HAVE_SYS_LOADAVG_H
98#include <sys/loadavg.h>
99#endif
100
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +0000101#ifdef HAVE_LANGINFO_H
102#include <langinfo.h>
103#endif
104
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000105#ifdef HAVE_SYS_SENDFILE_H
106#include <sys/sendfile.h>
107#endif
108
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500109#ifdef HAVE_SCHED_H
110#include <sched.h>
111#endif
112
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500113#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500114#undef HAVE_SCHED_SETAFFINITY
115#endif
116
Benjamin Peterson9428d532011-09-14 11:45:52 -0400117#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
118#define USE_XATTRS
119#endif
120
121#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400122#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400123#endif
124
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000125#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
126#ifdef HAVE_SYS_SOCKET_H
127#include <sys/socket.h>
128#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000129#endif
130
Victor Stinner8b905bd2011-10-25 13:34:04 +0200131#ifdef HAVE_DLFCN_H
132#include <dlfcn.h>
133#endif
134
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100135#if defined(MS_WINDOWS)
136# define TERMSIZE_USE_CONIO
137#elif defined(HAVE_SYS_IOCTL_H)
138# include <sys/ioctl.h>
139# if defined(HAVE_TERMIOS_H)
140# include <termios.h>
141# endif
142# if defined(TIOCGWINSZ)
143# define TERMSIZE_USE_IOCTL
144# endif
145#endif /* MS_WINDOWS */
146
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000147/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000148/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000149#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#include <process.h>
151#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_GETCWD 1
154#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#if defined(__OS2__)
157#define HAVE_EXECV 1
158#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000159#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#include <process.h>
161#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000163#define HAVE_EXECV 1
164#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_OPENDIR 1
166#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_WAIT 1
169#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000170#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000171#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000172#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000173#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#define HAVE_EXECV 1
176#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000177#define HAVE_SYSTEM 1
178#define HAVE_CWAIT 1
179#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000180#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000181#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000182#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
183/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000184#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185/* Unix functions that the configure script doesn't check for */
186#define HAVE_EXECV 1
187#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000188#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000189#define HAVE_FORK1 1
190#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000191#define HAVE_GETCWD 1
192#define HAVE_GETEGID 1
193#define HAVE_GETEUID 1
194#define HAVE_GETGID 1
195#define HAVE_GETPPID 1
196#define HAVE_GETUID 1
197#define HAVE_KILL 1
198#define HAVE_OPENDIR 1
199#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000200#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000202#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000203#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#endif /* _MSC_VER */
205#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000206#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000207#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000208
Victor Stinnera2f7c002012-02-08 03:36:25 +0100209
210
211
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000213
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000214#if defined(__sgi)&&_COMPILER_VERSION>=700
215/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
216 (default) */
217extern char *ctermid_r(char *);
218#endif
219
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000220#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000221#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000224#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000229#endif
230#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(char *);
232extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int chdir(const char *);
235extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000236#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000237#ifdef __BORLANDC__
238extern int chmod(const char *, int);
239#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000241#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000242/*#ifdef HAVE_FCHMOD
243extern int fchmod(int, mode_t);
244#endif*/
245/*#ifdef HAVE_LCHMOD
246extern int lchmod(const char *, mode_t);
247#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000248extern int chown(const char *, uid_t, gid_t);
249extern char *getcwd(char *, int);
250extern char *strerror(int);
251extern int link(const char *, const char *);
252extern int rename(const char *, const char *);
253extern int stat(const char *, struct stat *);
254extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000257#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000259extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000260#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000262
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000263#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#ifdef HAVE_UTIME_H
266#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000269#ifdef HAVE_SYS_UTIME_H
270#include <sys/utime.h>
271#define HAVE_UTIME_H /* pretend we do for the rest of this file */
272#endif /* HAVE_SYS_UTIME_H */
273
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#ifdef HAVE_SYS_TIMES_H
275#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000276#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
278#ifdef HAVE_SYS_PARAM_H
279#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000280#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281
282#ifdef HAVE_SYS_UTSNAME_H
283#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000284#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#define NAMLEN(dirent) strlen((dirent)->d_name)
289#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000290#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291#include <direct.h>
292#define NAMLEN(dirent) strlen((dirent)->d_name)
293#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000295#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000296#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000297#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000305#endif
306#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000308#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000309#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
315#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000316#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000317#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000318#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
324#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000325#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000326#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000328#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000329#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000330#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000331#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000332#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
333#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000334static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000335#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000336#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000337
Guido van Rossumd48f2521997-12-05 22:19:34 +0000338#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000339#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000340#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341
Tim Petersbc2e10e2002-03-03 23:17:02 +0000342#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000343#if defined(PATH_MAX) && PATH_MAX > 1024
344#define MAXPATHLEN PATH_MAX
345#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000346#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000347#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000348#endif /* MAXPATHLEN */
349
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000350#ifdef UNION_WAIT
351/* Emulate some macros on systems that have a union instead of macros */
352
353#ifndef WIFEXITED
354#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
355#endif
356
357#ifndef WEXITSTATUS
358#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
359#endif
360
361#ifndef WTERMSIG
362#define WTERMSIG(u_wait) ((u_wait).w_termsig)
363#endif
364
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000365#define WAIT_TYPE union wait
366#define WAIT_STATUS_INT(s) (s.w_status)
367
368#else /* !UNION_WAIT */
369#define WAIT_TYPE int
370#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000371#endif /* UNION_WAIT */
372
Greg Wardb48bc172000-03-01 21:51:56 +0000373/* Don't use the "_r" form if we don't need it (also, won't have a
374 prototype for it, at least on Solaris -- maybe others as well?). */
375#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
376#define USE_CTERMID_R
377#endif
378
Fred Drake699f3522000-06-29 21:12:41 +0000379/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000380#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000381#undef FSTAT
382#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000383#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000384# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700385# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000386# define FSTAT win32_fstat
387# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000388#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000389# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700390# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000391# define FSTAT fstat
392# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000393#endif
394
Tim Peters11b23062003-04-23 02:39:17 +0000395#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000396#include <sys/mkdev.h>
397#else
398#if defined(MAJOR_IN_SYSMACROS)
399#include <sys/sysmacros.h>
400#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000401#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
402#include <sys/mkdev.h>
403#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000404#endif
Fred Drake699f3522000-06-29 21:12:41 +0000405
Larry Hastings9cf065c2012-06-22 16:30:09 -0700406
407#ifdef MS_WINDOWS
408static int
409win32_warn_bytes_api()
410{
411 return PyErr_WarnEx(PyExc_DeprecationWarning,
412 "The Windows bytes API has been deprecated, "
413 "use Unicode filenames instead",
414 1);
415}
416#endif
417
418
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200419#ifndef MS_WINDOWS
420PyObject *
421_PyLong_FromUid(uid_t uid)
422{
423 if (uid == (uid_t)-1)
424 return PyLong_FromLong(-1);
425 return PyLong_FromUnsignedLong(uid);
426}
427
428PyObject *
429_PyLong_FromGid(gid_t gid)
430{
431 if (gid == (gid_t)-1)
432 return PyLong_FromLong(-1);
433 return PyLong_FromUnsignedLong(gid);
434}
435
436int
437_Py_Uid_Converter(PyObject *obj, void *p)
438{
439 int overflow;
440 long result = PyLong_AsLongAndOverflow(obj, &overflow);
441 if (overflow < 0)
442 goto OverflowDown;
443 if (!overflow && result == -1) {
444 /* error or -1 */
445 if (PyErr_Occurred())
446 return 0;
447 *(uid_t *)p = (uid_t)-1;
448 }
449 else {
450 /* unsigned uid_t */
451 unsigned long uresult;
452 if (overflow > 0) {
453 uresult = PyLong_AsUnsignedLong(obj);
454 if (PyErr_Occurred()) {
455 if (PyErr_ExceptionMatches(PyExc_OverflowError))
456 goto OverflowUp;
457 return 0;
458 }
459 if ((uid_t)uresult == (uid_t)-1)
460 goto OverflowUp;
461 } else {
462 if (result < 0)
463 goto OverflowDown;
464 uresult = result;
465 }
466 if (sizeof(uid_t) < sizeof(long) &&
467 (unsigned long)(uid_t)uresult != uresult)
468 goto OverflowUp;
469 *(uid_t *)p = (uid_t)uresult;
470 }
471 return 1;
472
473OverflowDown:
474 PyErr_SetString(PyExc_OverflowError,
475 "user id is less than minimum");
476 return 0;
477
478OverflowUp:
479 PyErr_SetString(PyExc_OverflowError,
480 "user id is greater than maximum");
481 return 0;
482}
483
484int
485_Py_Gid_Converter(PyObject *obj, void *p)
486{
487 int overflow;
488 long result = PyLong_AsLongAndOverflow(obj, &overflow);
489 if (overflow < 0)
490 goto OverflowDown;
491 if (!overflow && result == -1) {
492 /* error or -1 */
493 if (PyErr_Occurred())
494 return 0;
495 *(gid_t *)p = (gid_t)-1;
496 }
497 else {
498 /* unsigned gid_t */
499 unsigned long uresult;
500 if (overflow > 0) {
501 uresult = PyLong_AsUnsignedLong(obj);
502 if (PyErr_Occurred()) {
503 if (PyErr_ExceptionMatches(PyExc_OverflowError))
504 goto OverflowUp;
505 return 0;
506 }
507 if ((gid_t)uresult == (gid_t)-1)
508 goto OverflowUp;
509 } else {
510 if (result < 0)
511 goto OverflowDown;
512 uresult = result;
513 }
514 if (sizeof(gid_t) < sizeof(long) &&
515 (unsigned long)(gid_t)uresult != uresult)
516 goto OverflowUp;
517 *(gid_t *)p = (gid_t)uresult;
518 }
519 return 1;
520
521OverflowDown:
522 PyErr_SetString(PyExc_OverflowError,
523 "group id is less than minimum");
524 return 0;
525
526OverflowUp:
527 PyErr_SetString(PyExc_OverflowError,
528 "group id is greater than maximum");
529 return 0;
530}
531#endif /* MS_WINDOWS */
532
533
Larry Hastings9cf065c2012-06-22 16:30:09 -0700534#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400535/*
536 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
537 * without the int cast, the value gets interpreted as uint (4291925331),
538 * which doesn't play nicely with all the initializer lines in this file that
539 * look like this:
540 * int dir_fd = DEFAULT_DIR_FD;
541 */
542#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700543#else
544#define DEFAULT_DIR_FD (-100)
545#endif
546
547static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200548_fd_converter(PyObject *o, int *p, const char *allowed)
549{
550 int overflow;
551 long long_value = PyLong_AsLongAndOverflow(o, &overflow);
552 if (PyFloat_Check(o) ||
553 (long_value == -1 && !overflow && PyErr_Occurred())) {
554 PyErr_Clear();
555 PyErr_Format(PyExc_TypeError,
556 "argument should be %s, not %.200s",
557 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700558 return 0;
559 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200560 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700561 PyErr_SetString(PyExc_OverflowError,
562 "signed integer is greater than maximum");
563 return 0;
564 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200565 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700566 PyErr_SetString(PyExc_OverflowError,
567 "signed integer is less than minimum");
568 return 0;
569 }
570 *p = (int)long_value;
571 return 1;
572}
573
574static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200575dir_fd_converter(PyObject *o, void *p)
576{
577 if (o == Py_None) {
578 *(int *)p = DEFAULT_DIR_FD;
579 return 1;
580 }
581 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700582}
583
584
585
586/*
587 * A PyArg_ParseTuple "converter" function
588 * that handles filesystem paths in the manner
589 * preferred by the os module.
590 *
591 * path_converter accepts (Unicode) strings and their
592 * subclasses, and bytes and their subclasses. What
593 * it does with the argument depends on the platform:
594 *
595 * * On Windows, if we get a (Unicode) string we
596 * extract the wchar_t * and return it; if we get
597 * bytes we extract the char * and return that.
598 *
599 * * On all other platforms, strings are encoded
600 * to bytes using PyUnicode_FSConverter, then we
601 * extract the char * from the bytes object and
602 * return that.
603 *
604 * path_converter also optionally accepts signed
605 * integers (representing open file descriptors) instead
606 * of path strings.
607 *
608 * Input fields:
609 * path.nullable
610 * If nonzero, the path is permitted to be None.
611 * path.allow_fd
612 * If nonzero, the path is permitted to be a file handle
613 * (a signed int) instead of a string.
614 * path.function_name
615 * If non-NULL, path_converter will use that as the name
616 * of the function in error messages.
617 * (If path.argument_name is NULL it omits the function name.)
618 * path.argument_name
619 * If non-NULL, path_converter will use that as the name
620 * of the parameter in error messages.
621 * (If path.argument_name is NULL it uses "path".)
622 *
623 * Output fields:
624 * path.wide
625 * Points to the path if it was expressed as Unicode
626 * and was not encoded. (Only used on Windows.)
627 * path.narrow
628 * Points to the path if it was expressed as bytes,
629 * or it was Unicode and was encoded to bytes.
630 * path.fd
631 * Contains a file descriptor if path.accept_fd was true
632 * and the caller provided a signed integer instead of any
633 * sort of string.
634 *
635 * WARNING: if your "path" parameter is optional, and is
636 * unspecified, path_converter will never get called.
637 * So if you set allow_fd, you *MUST* initialize path.fd = -1
638 * yourself!
639 * path.length
640 * The length of the path in characters, if specified as
641 * a string.
642 * path.object
643 * The original object passed in.
644 * path.cleanup
645 * For internal use only. May point to a temporary object.
646 * (Pay no attention to the man behind the curtain.)
647 *
648 * At most one of path.wide or path.narrow will be non-NULL.
649 * If path was None and path.nullable was set,
650 * or if path was an integer and path.allow_fd was set,
651 * both path.wide and path.narrow will be NULL
652 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200653 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700654 * path_converter takes care to not write to the path_t
655 * unless it's successful. However it must reset the
656 * "cleanup" field each time it's called.
657 *
658 * Use as follows:
659 * path_t path;
660 * memset(&path, 0, sizeof(path));
661 * PyArg_ParseTuple(args, "O&", path_converter, &path);
662 * // ... use values from path ...
663 * path_cleanup(&path);
664 *
665 * (Note that if PyArg_Parse fails you don't need to call
666 * path_cleanup(). However it is safe to do so.)
667 */
668typedef struct {
669 char *function_name;
670 char *argument_name;
671 int nullable;
672 int allow_fd;
673 wchar_t *wide;
674 char *narrow;
675 int fd;
676 Py_ssize_t length;
677 PyObject *object;
678 PyObject *cleanup;
679} path_t;
680
681static void
682path_cleanup(path_t *path) {
683 if (path->cleanup) {
684 Py_DECREF(path->cleanup);
685 path->cleanup = NULL;
686 }
687}
688
689static int
690path_converter(PyObject *o, void *p) {
691 path_t *path = (path_t *)p;
692 PyObject *unicode, *bytes;
693 Py_ssize_t length;
694 char *narrow;
695
696#define FORMAT_EXCEPTION(exc, fmt) \
697 PyErr_Format(exc, "%s%s" fmt, \
698 path->function_name ? path->function_name : "", \
699 path->function_name ? ": " : "", \
700 path->argument_name ? path->argument_name : "path")
701
702 /* Py_CLEANUP_SUPPORTED support */
703 if (o == NULL) {
704 path_cleanup(path);
705 return 1;
706 }
707
708 /* ensure it's always safe to call path_cleanup() */
709 path->cleanup = NULL;
710
711 if (o == Py_None) {
712 if (!path->nullable) {
713 FORMAT_EXCEPTION(PyExc_TypeError,
714 "can't specify None for %s argument");
715 return 0;
716 }
717 path->wide = NULL;
718 path->narrow = NULL;
719 path->length = 0;
720 path->object = o;
721 path->fd = -1;
722 return 1;
723 }
724
725 unicode = PyUnicode_FromObject(o);
726 if (unicode) {
727#ifdef MS_WINDOWS
728 wchar_t *wide;
729 length = PyUnicode_GET_SIZE(unicode);
730 if (length > 32767) {
731 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
732 Py_DECREF(unicode);
733 return 0;
734 }
735
736 wide = PyUnicode_AsUnicode(unicode);
737 if (!wide) {
738 Py_DECREF(unicode);
739 return 0;
740 }
741
742 path->wide = wide;
743 path->narrow = NULL;
744 path->length = length;
745 path->object = o;
746 path->fd = -1;
747 path->cleanup = unicode;
748 return Py_CLEANUP_SUPPORTED;
749#else
750 int converted = PyUnicode_FSConverter(unicode, &bytes);
751 Py_DECREF(unicode);
752 if (!converted)
753 bytes = NULL;
754#endif
755 }
756 else {
757 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200758 if (PyObject_CheckBuffer(o))
759 bytes = PyBytes_FromObject(o);
760 else
761 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700762 if (!bytes) {
763 PyErr_Clear();
764 if (path->allow_fd) {
765 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200766 int result = _fd_converter(o, &fd,
767 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700768 if (result) {
769 path->wide = NULL;
770 path->narrow = NULL;
771 path->length = 0;
772 path->object = o;
773 path->fd = fd;
774 return result;
775 }
776 }
777 }
778 }
779
780 if (!bytes) {
781 if (!PyErr_Occurred())
782 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
783 return 0;
784 }
785
786#ifdef MS_WINDOWS
787 if (win32_warn_bytes_api()) {
788 Py_DECREF(bytes);
789 return 0;
790 }
791#endif
792
793 length = PyBytes_GET_SIZE(bytes);
794#ifdef MS_WINDOWS
795 if (length > MAX_PATH) {
796 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
797 Py_DECREF(bytes);
798 return 0;
799 }
800#endif
801
802 narrow = PyBytes_AS_STRING(bytes);
803 if (length != strlen(narrow)) {
804 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
805 Py_DECREF(bytes);
806 return 0;
807 }
808
809 path->wide = NULL;
810 path->narrow = narrow;
811 path->length = length;
812 path->object = o;
813 path->fd = -1;
814 path->cleanup = bytes;
815 return Py_CLEANUP_SUPPORTED;
816}
817
818static void
819argument_unavailable_error(char *function_name, char *argument_name) {
820 PyErr_Format(PyExc_NotImplementedError,
821 "%s%s%s unavailable on this platform",
822 (function_name != NULL) ? function_name : "",
823 (function_name != NULL) ? ": ": "",
824 argument_name);
825}
826
827static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200828dir_fd_unavailable(PyObject *o, void *p)
829{
830 int dir_fd;
831 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700832 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200833 if (dir_fd != DEFAULT_DIR_FD) {
834 argument_unavailable_error(NULL, "dir_fd");
835 return 0;
836 }
837 *(int *)p = dir_fd;
838 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700839}
840
841static int
842fd_specified(char *function_name, int fd) {
843 if (fd == -1)
844 return 0;
845
846 argument_unavailable_error(function_name, "fd");
847 return 1;
848}
849
850static int
851follow_symlinks_specified(char *function_name, int follow_symlinks) {
852 if (follow_symlinks)
853 return 0;
854
855 argument_unavailable_error(function_name, "follow_symlinks");
856 return 1;
857}
858
859static int
860path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
861 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
862 PyErr_Format(PyExc_ValueError,
863 "%s: can't specify dir_fd without matching path",
864 function_name);
865 return 1;
866 }
867 return 0;
868}
869
870static int
871dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
872 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
873 PyErr_Format(PyExc_ValueError,
874 "%s: can't specify both dir_fd and fd",
875 function_name);
876 return 1;
877 }
878 return 0;
879}
880
881static int
882fd_and_follow_symlinks_invalid(char *function_name, int fd,
883 int follow_symlinks) {
884 if ((fd > 0) && (!follow_symlinks)) {
885 PyErr_Format(PyExc_ValueError,
886 "%s: cannot use fd and follow_symlinks together",
887 function_name);
888 return 1;
889 }
890 return 0;
891}
892
893static int
894dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
895 int follow_symlinks) {
896 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
897 PyErr_Format(PyExc_ValueError,
898 "%s: cannot use dir_fd and follow_symlinks together",
899 function_name);
900 return 1;
901 }
902 return 0;
903}
904
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200905/* A helper used by a number of POSIX-only functions */
906#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000907static int
908_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000909{
910#if !defined(HAVE_LARGEFILE_SUPPORT)
911 *((off_t*)addr) = PyLong_AsLong(arg);
912#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000913 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000914#endif
915 if (PyErr_Occurred())
916 return 0;
917 return 1;
918}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200919#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000920
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000921#if defined _MSC_VER && _MSC_VER >= 1400
922/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200923 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000924 * Normally, an invalid fd is likely to be a C program error and therefore
925 * an assertion can be useful, but it does contradict the POSIX standard
926 * which for write(2) states:
927 * "Otherwise, -1 shall be returned and errno set to indicate the error."
928 * "[EBADF] The fildes argument is not a valid file descriptor open for
929 * writing."
930 * Furthermore, python allows the user to enter any old integer
931 * as a fd and should merely raise a python exception on error.
932 * The Microsoft CRT doesn't provide an official way to check for the
933 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000934 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000935 * internal structures involved.
936 * The structures below must be updated for each version of visual studio
937 * according to the file internal.h in the CRT source, until MS comes
938 * up with a less hacky way to do this.
939 * (all of this is to avoid globally modifying the CRT behaviour using
940 * _set_invalid_parameter_handler() and _CrtSetReportMode())
941 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000942/* The actual size of the structure is determined at runtime.
943 * Only the first items must be present.
944 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000945typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000946 intptr_t osfhnd;
947 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000948} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000949
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000950extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000951#define IOINFO_L2E 5
952#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
953#define IOINFO_ARRAYS 64
954#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
955#define FOPEN 0x01
956#define _NO_CONSOLE_FILENO (intptr_t)-2
957
958/* This function emulates what the windows CRT does to validate file handles */
959int
960_PyVerify_fd(int fd)
961{
Victor Stinner8c62be82010-05-06 00:08:46 +0000962 const int i1 = fd >> IOINFO_L2E;
963 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000964
Antoine Pitrou22e41552010-08-15 18:07:50 +0000965 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000966
Victor Stinner8c62be82010-05-06 00:08:46 +0000967 /* Determine the actual size of the ioinfo structure,
968 * as used by the CRT loaded in memory
969 */
970 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
971 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
972 }
973 if (sizeof_ioinfo == 0) {
974 /* This should not happen... */
975 goto fail;
976 }
977
978 /* See that it isn't a special CLEAR fileno */
979 if (fd != _NO_CONSOLE_FILENO) {
980 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
981 * we check pointer validity and other info
982 */
983 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
984 /* finally, check that the file is open */
985 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
986 if (info->osfile & FOPEN) {
987 return 1;
988 }
989 }
990 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000991 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000992 errno = EBADF;
993 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000994}
995
996/* the special case of checking dup2. The target fd must be in a sensible range */
997static int
998_PyVerify_fd_dup2(int fd1, int fd2)
999{
Victor Stinner8c62be82010-05-06 00:08:46 +00001000 if (!_PyVerify_fd(fd1))
1001 return 0;
1002 if (fd2 == _NO_CONSOLE_FILENO)
1003 return 0;
1004 if ((unsigned)fd2 < _NHANDLE_)
1005 return 1;
1006 else
1007 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001008}
1009#else
1010/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1011#define _PyVerify_fd_dup2(A, B) (1)
1012#endif
1013
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001014#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001015/* The following structure was copied from
1016 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1017 include doesn't seem to be present in the Windows SDK (at least as included
1018 with Visual Studio Express). */
1019typedef struct _REPARSE_DATA_BUFFER {
1020 ULONG ReparseTag;
1021 USHORT ReparseDataLength;
1022 USHORT Reserved;
1023 union {
1024 struct {
1025 USHORT SubstituteNameOffset;
1026 USHORT SubstituteNameLength;
1027 USHORT PrintNameOffset;
1028 USHORT PrintNameLength;
1029 ULONG Flags;
1030 WCHAR PathBuffer[1];
1031 } SymbolicLinkReparseBuffer;
1032
1033 struct {
1034 USHORT SubstituteNameOffset;
1035 USHORT SubstituteNameLength;
1036 USHORT PrintNameOffset;
1037 USHORT PrintNameLength;
1038 WCHAR PathBuffer[1];
1039 } MountPointReparseBuffer;
1040
1041 struct {
1042 UCHAR DataBuffer[1];
1043 } GenericReparseBuffer;
1044 };
1045} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1046
1047#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1048 GenericReparseBuffer)
1049#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1050
1051static int
Brian Curtind25aef52011-06-13 15:16:04 -05001052win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001053{
1054 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1055 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1056 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001057
1058 if (0 == DeviceIoControl(
1059 reparse_point_handle,
1060 FSCTL_GET_REPARSE_POINT,
1061 NULL, 0, /* in buffer */
1062 target_buffer, sizeof(target_buffer),
1063 &n_bytes_returned,
1064 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001065 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001066
1067 if (reparse_tag)
1068 *reparse_tag = rdb->ReparseTag;
1069
Brian Curtind25aef52011-06-13 15:16:04 -05001070 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001071}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001072
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001073#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001074
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001075/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001076#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001077/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001078** environ directly, we must obtain it with _NSGetEnviron(). See also
1079** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001080*/
1081#include <crt_externs.h>
1082static char **environ;
1083#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001084extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001085#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001086
Barry Warsaw53699e91996-12-10 23:23:01 +00001087static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001088convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001089{
Victor Stinner8c62be82010-05-06 00:08:46 +00001090 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001091#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001092 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001093#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001094 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001095#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001096#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001097 APIRET rc;
1098 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
1099#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001100
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 d = PyDict_New();
1102 if (d == NULL)
1103 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001104#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001105 if (environ == NULL)
1106 environ = *_NSGetEnviron();
1107#endif
1108#ifdef MS_WINDOWS
1109 /* _wenviron must be initialized in this way if the program is started
1110 through main() instead of wmain(). */
1111 _wgetenv(L"");
1112 if (_wenviron == NULL)
1113 return d;
1114 /* This part ignores errors */
1115 for (e = _wenviron; *e != NULL; e++) {
1116 PyObject *k;
1117 PyObject *v;
1118 wchar_t *p = wcschr(*e, L'=');
1119 if (p == NULL)
1120 continue;
1121 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1122 if (k == NULL) {
1123 PyErr_Clear();
1124 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001125 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001126 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1127 if (v == NULL) {
1128 PyErr_Clear();
1129 Py_DECREF(k);
1130 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001131 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001132 if (PyDict_GetItem(d, k) == NULL) {
1133 if (PyDict_SetItem(d, k, v) != 0)
1134 PyErr_Clear();
1135 }
1136 Py_DECREF(k);
1137 Py_DECREF(v);
1138 }
1139#else
1140 if (environ == NULL)
1141 return d;
1142 /* This part ignores errors */
1143 for (e = environ; *e != NULL; e++) {
1144 PyObject *k;
1145 PyObject *v;
1146 char *p = strchr(*e, '=');
1147 if (p == NULL)
1148 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001149 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001150 if (k == NULL) {
1151 PyErr_Clear();
1152 continue;
1153 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001154 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001155 if (v == NULL) {
1156 PyErr_Clear();
1157 Py_DECREF(k);
1158 continue;
1159 }
1160 if (PyDict_GetItem(d, k) == NULL) {
1161 if (PyDict_SetItem(d, k, v) != 0)
1162 PyErr_Clear();
1163 }
1164 Py_DECREF(k);
1165 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001166 }
1167#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001168#if defined(PYOS_OS2)
1169 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1170 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1171 PyObject *v = PyBytes_FromString(buffer);
1172 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1173 Py_DECREF(v);
1174 }
1175 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1176 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1177 PyObject *v = PyBytes_FromString(buffer);
1178 PyDict_SetItemString(d, "ENDLIBPATH", v);
1179 Py_DECREF(v);
1180 }
1181#endif
1182 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183}
1184
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185/* Set a POSIX-specific error from errno, and return NULL */
1186
Barry Warsawd58d7641998-07-23 16:14:40 +00001187static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001188posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001189{
Victor Stinner8c62be82010-05-06 00:08:46 +00001190 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191}
Barry Warsawd58d7641998-07-23 16:14:40 +00001192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001193posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001194{
Victor Stinner8c62be82010-05-06 00:08:46 +00001195 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001196}
1197
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001198
Mark Hammondef8b6542001-05-13 08:04:26 +00001199static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001200posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001201{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001202 PyObject *name_str, *rc;
1203 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1204 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001205 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001206 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1207 name_str);
1208 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001209 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001210}
1211
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001212#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001213static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001214win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001215{
Victor Stinner8c62be82010-05-06 00:08:46 +00001216 /* XXX We should pass the function name along in the future.
1217 (winreg.c also wants to pass the function name.)
1218 This would however require an additional param to the
1219 Windows error object, which is non-trivial.
1220 */
1221 errno = GetLastError();
1222 if (filename)
1223 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1224 else
1225 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001226}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001227
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001228static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001229win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001230{
Victor Stinner8c62be82010-05-06 00:08:46 +00001231 /* XXX - see win32_error for comments on 'function' */
1232 errno = GetLastError();
1233 if (filename)
1234 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1235 else
1236 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001237}
1238
Victor Stinnereb5657a2011-09-30 01:44:27 +02001239static PyObject *
1240win32_error_object(char* function, PyObject* filename)
1241{
1242 /* XXX - see win32_error for comments on 'function' */
1243 errno = GetLastError();
1244 if (filename)
1245 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1246 PyExc_WindowsError,
1247 errno,
1248 filename);
1249 else
1250 return PyErr_SetFromWindowsErr(errno);
1251}
1252
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001253#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254
Larry Hastings9cf065c2012-06-22 16:30:09 -07001255/*
1256 * Some functions return Win32 errors, others only ever use posix_error
1257 * (this is for backwards compatibility with exceptions)
1258 */
1259static PyObject *
1260path_posix_error(char *function_name, path_t *path)
1261{
1262 if (path->narrow)
1263 return posix_error_with_filename(path->narrow);
1264 return posix_error();
1265}
1266
1267static PyObject *
1268path_error(char *function_name, path_t *path)
1269{
1270#ifdef MS_WINDOWS
1271 if (path->narrow)
1272 return win32_error(function_name, path->narrow);
1273 if (path->wide)
1274 return win32_error_unicode(function_name, path->wide);
1275 return win32_error(function_name, NULL);
1276#else
1277 return path_posix_error(function_name, path);
1278#endif
1279}
1280
Guido van Rossumd48f2521997-12-05 22:19:34 +00001281#if defined(PYOS_OS2)
1282/**********************************************************************
1283 * Helper Function to Trim and Format OS/2 Messages
1284 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001285static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001286os2_formatmsg(char *msgbuf, int msglen, char *reason)
1287{
1288 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1289
1290 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1291 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1292
Antoine Pitrou4de74572013-02-09 23:11:27 +01001293 while (lastc > msgbuf && Py_ISSPACE(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001294 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1295 }
1296
1297 /* Add Optional Reason Text */
1298 if (reason) {
1299 strcat(msgbuf, " : ");
1300 strcat(msgbuf, reason);
1301 }
1302}
1303
1304/**********************************************************************
1305 * Decode an OS/2 Operating System Error Code
1306 *
1307 * A convenience function to lookup an OS/2 error code and return a
1308 * text message we can use to raise a Python exception.
1309 *
1310 * Notes:
1311 * The messages for errors returned from the OS/2 kernel reside in
1312 * the file OSO001.MSG in the \OS2 directory hierarchy.
1313 *
1314 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001315static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001316os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1317{
1318 APIRET rc;
1319 ULONG msglen;
1320
1321 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1322 Py_BEGIN_ALLOW_THREADS
1323 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1324 errorcode, "oso001.msg", &msglen);
1325 Py_END_ALLOW_THREADS
1326
1327 if (rc == NO_ERROR)
1328 os2_formatmsg(msgbuf, msglen, reason);
1329 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001330 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001331 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001332
1333 return msgbuf;
1334}
1335
1336/* Set an OS/2-specific error and return NULL. OS/2 kernel
1337 errors are not in a global variable e.g. 'errno' nor are
1338 they congruent with posix error numbers. */
1339
Victor Stinner8c62be82010-05-06 00:08:46 +00001340static PyObject *
1341os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001342{
1343 char text[1024];
1344 PyObject *v;
1345
1346 os2_strerror(text, sizeof(text), code, "");
1347
1348 v = Py_BuildValue("(is)", code, text);
1349 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001350 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001351 Py_DECREF(v);
1352 }
1353 return NULL; /* Signal to Python that an Exception is Pending */
1354}
1355
1356#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357
1358/* POSIX generic methods */
1359
Barry Warsaw53699e91996-12-10 23:23:01 +00001360static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001361posix_fildes(PyObject *fdobj, int (*func)(int))
1362{
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 int fd;
1364 int res;
1365 fd = PyObject_AsFileDescriptor(fdobj);
1366 if (fd < 0)
1367 return NULL;
1368 if (!_PyVerify_fd(fd))
1369 return posix_error();
1370 Py_BEGIN_ALLOW_THREADS
1371 res = (*func)(fd);
1372 Py_END_ALLOW_THREADS
1373 if (res < 0)
1374 return posix_error();
1375 Py_INCREF(Py_None);
1376 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001377}
Guido van Rossum21142a01999-01-08 21:05:37 +00001378
1379static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001380posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001381{
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 PyObject *opath1 = NULL;
1383 char *path1;
1384 int res;
1385 if (!PyArg_ParseTuple(args, format,
1386 PyUnicode_FSConverter, &opath1))
1387 return NULL;
1388 path1 = PyBytes_AsString(opath1);
1389 Py_BEGIN_ALLOW_THREADS
1390 res = (*func)(path1);
1391 Py_END_ALLOW_THREADS
1392 if (res < 0)
1393 return posix_error_with_allocated_filename(opath1);
1394 Py_DECREF(opath1);
1395 Py_INCREF(Py_None);
1396 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001397}
1398
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001399
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001400#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001401static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001402win32_1str(PyObject* args, char* func,
1403 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1404 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001405{
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001407 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001408 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001409
Victor Stinnereb5657a2011-09-30 01:44:27 +02001410 if (PyArg_ParseTuple(args, wformat, &uni))
1411 {
1412 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1413 if (wstr == NULL)
1414 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001415 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001416 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001417 Py_END_ALLOW_THREADS
1418 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001419 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 Py_INCREF(Py_None);
1421 return Py_None;
1422 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001423 PyErr_Clear();
1424
Victor Stinner8c62be82010-05-06 00:08:46 +00001425 if (!PyArg_ParseTuple(args, format, &ansi))
1426 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001427 if (win32_warn_bytes_api())
1428 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 Py_BEGIN_ALLOW_THREADS
1430 result = funcA(ansi);
1431 Py_END_ALLOW_THREADS
1432 if (!result)
1433 return win32_error(func, ansi);
1434 Py_INCREF(Py_None);
1435 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001436
1437}
1438
1439/* This is a reimplementation of the C library's chdir function,
1440 but one that produces Win32 errors instead of DOS error codes.
1441 chdir is essentially a wrapper around SetCurrentDirectory; however,
1442 it also needs to set "magic" environment variables indicating
1443 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001444static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001445win32_chdir(LPCSTR path)
1446{
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 char new_path[MAX_PATH+1];
1448 int result;
1449 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001450
Victor Stinner8c62be82010-05-06 00:08:46 +00001451 if(!SetCurrentDirectoryA(path))
1452 return FALSE;
1453 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1454 if (!result)
1455 return FALSE;
1456 /* In the ANSI API, there should not be any paths longer
1457 than MAX_PATH. */
1458 assert(result <= MAX_PATH+1);
1459 if (strncmp(new_path, "\\\\", 2) == 0 ||
1460 strncmp(new_path, "//", 2) == 0)
1461 /* UNC path, nothing to do. */
1462 return TRUE;
1463 env[1] = new_path[0];
1464 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001465}
1466
1467/* The Unicode version differs from the ANSI version
1468 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001469static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001470win32_wchdir(LPCWSTR path)
1471{
Victor Stinner8c62be82010-05-06 00:08:46 +00001472 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1473 int result;
1474 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475
Victor Stinner8c62be82010-05-06 00:08:46 +00001476 if(!SetCurrentDirectoryW(path))
1477 return FALSE;
1478 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1479 if (!result)
1480 return FALSE;
1481 if (result > MAX_PATH+1) {
1482 new_path = malloc(result * sizeof(wchar_t));
1483 if (!new_path) {
1484 SetLastError(ERROR_OUTOFMEMORY);
1485 return FALSE;
1486 }
1487 result = GetCurrentDirectoryW(result, new_path);
1488 if (!result) {
1489 free(new_path);
1490 return FALSE;
1491 }
1492 }
1493 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1494 wcsncmp(new_path, L"//", 2) == 0)
1495 /* UNC path, nothing to do. */
1496 return TRUE;
1497 env[1] = new_path[0];
1498 result = SetEnvironmentVariableW(env, new_path);
1499 if (new_path != _new_path)
1500 free(new_path);
1501 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001502}
1503#endif
1504
Martin v. Löwis14694662006-02-03 12:54:16 +00001505#ifdef MS_WINDOWS
1506/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1507 - time stamps are restricted to second resolution
1508 - file modification times suffer from forth-and-back conversions between
1509 UTC and local time
1510 Therefore, we implement our own stat, based on the Win32 API directly.
1511*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001512#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001513
1514struct win32_stat{
1515 int st_dev;
1516 __int64 st_ino;
1517 unsigned short st_mode;
1518 int st_nlink;
1519 int st_uid;
1520 int st_gid;
1521 int st_rdev;
1522 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001523 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001524 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001525 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001526 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001527 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001528 int st_ctime_nsec;
1529};
1530
1531static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1532
1533static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001534FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001535{
Victor Stinner8c62be82010-05-06 00:08:46 +00001536 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1537 /* Cannot simply cast and dereference in_ptr,
1538 since it might not be aligned properly */
1539 __int64 in;
1540 memcpy(&in, in_ptr, sizeof(in));
1541 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001542 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001543}
1544
Thomas Wouters477c8d52006-05-27 19:21:47 +00001545static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001546time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547{
Victor Stinner8c62be82010-05-06 00:08:46 +00001548 /* XXX endianness */
1549 __int64 out;
1550 out = time_in + secs_between_epochs;
1551 out = out * 10000000 + nsec_in / 100;
1552 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001553}
1554
Martin v. Löwis14694662006-02-03 12:54:16 +00001555/* Below, we *know* that ugo+r is 0444 */
1556#if _S_IREAD != 0400
1557#error Unsupported C library
1558#endif
1559static int
1560attributes_to_mode(DWORD attr)
1561{
Victor Stinner8c62be82010-05-06 00:08:46 +00001562 int m = 0;
1563 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1564 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1565 else
1566 m |= _S_IFREG;
1567 if (attr & FILE_ATTRIBUTE_READONLY)
1568 m |= 0444;
1569 else
1570 m |= 0666;
1571 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001572}
1573
1574static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001575attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001576{
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 memset(result, 0, sizeof(*result));
1578 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1579 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1580 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1581 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1582 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001584 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001585 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1586 /* first clear the S_IFMT bits */
1587 result->st_mode ^= (result->st_mode & 0170000);
1588 /* now set the bits that make this a symlink */
1589 result->st_mode |= 0120000;
1590 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001591
Victor Stinner8c62be82010-05-06 00:08:46 +00001592 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001593}
1594
Guido van Rossumd8faa362007-04-27 19:54:29 +00001595static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001596attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001597{
Victor Stinner8c62be82010-05-06 00:08:46 +00001598 HANDLE hFindFile;
1599 WIN32_FIND_DATAA FileData;
1600 hFindFile = FindFirstFileA(pszFile, &FileData);
1601 if (hFindFile == INVALID_HANDLE_VALUE)
1602 return FALSE;
1603 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001604 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001605 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001606 info->dwFileAttributes = FileData.dwFileAttributes;
1607 info->ftCreationTime = FileData.ftCreationTime;
1608 info->ftLastAccessTime = FileData.ftLastAccessTime;
1609 info->ftLastWriteTime = FileData.ftLastWriteTime;
1610 info->nFileSizeHigh = FileData.nFileSizeHigh;
1611 info->nFileSizeLow = FileData.nFileSizeLow;
1612/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1614 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001615 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001616}
1617
1618static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001619attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001620{
Victor Stinner8c62be82010-05-06 00:08:46 +00001621 HANDLE hFindFile;
1622 WIN32_FIND_DATAW FileData;
1623 hFindFile = FindFirstFileW(pszFile, &FileData);
1624 if (hFindFile == INVALID_HANDLE_VALUE)
1625 return FALSE;
1626 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001627 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001628 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001629 info->dwFileAttributes = FileData.dwFileAttributes;
1630 info->ftCreationTime = FileData.ftCreationTime;
1631 info->ftLastAccessTime = FileData.ftLastAccessTime;
1632 info->ftLastWriteTime = FileData.ftLastWriteTime;
1633 info->nFileSizeHigh = FileData.nFileSizeHigh;
1634 info->nFileSizeLow = FileData.nFileSizeLow;
1635/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001636 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1637 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001638 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001639}
1640
Brian Curtind25aef52011-06-13 15:16:04 -05001641/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1642static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001643static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1644 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001645static int
Brian Curtind25aef52011-06-13 15:16:04 -05001646check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001647{
Brian Curtind25aef52011-06-13 15:16:04 -05001648 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001649 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1650 DWORD);
1651
Brian Curtind25aef52011-06-13 15:16:04 -05001652 /* only recheck */
1653 if (!has_GetFinalPathNameByHandle)
1654 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001655 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001656 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1657 "GetFinalPathNameByHandleA");
1658 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1659 "GetFinalPathNameByHandleW");
1660 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1661 Py_GetFinalPathNameByHandleW;
1662 }
1663 return has_GetFinalPathNameByHandle;
1664}
1665
1666static BOOL
1667get_target_path(HANDLE hdl, wchar_t **target_path)
1668{
1669 int buf_size, result_length;
1670 wchar_t *buf;
1671
1672 /* We have a good handle to the target, use it to determine
1673 the target path name (then we'll call lstat on it). */
1674 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1675 VOLUME_NAME_DOS);
1676 if(!buf_size)
1677 return FALSE;
1678
1679 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001680 if (!buf) {
1681 SetLastError(ERROR_OUTOFMEMORY);
1682 return FALSE;
1683 }
1684
Brian Curtind25aef52011-06-13 15:16:04 -05001685 result_length = Py_GetFinalPathNameByHandleW(hdl,
1686 buf, buf_size, VOLUME_NAME_DOS);
1687
1688 if(!result_length) {
1689 free(buf);
1690 return FALSE;
1691 }
1692
1693 if(!CloseHandle(hdl)) {
1694 free(buf);
1695 return FALSE;
1696 }
1697
1698 buf[result_length] = 0;
1699
1700 *target_path = buf;
1701 return TRUE;
1702}
1703
1704static int
1705win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1706 BOOL traverse);
1707static int
1708win32_xstat_impl(const char *path, struct win32_stat *result,
1709 BOOL traverse)
1710{
Victor Stinner26de69d2011-06-17 15:15:38 +02001711 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001712 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001713 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001715 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001716 const char *dot;
1717
Brian Curtind25aef52011-06-13 15:16:04 -05001718 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001719 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1720 traverse reparse point. */
1721 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001722 }
1723
Brian Curtinf5e76d02010-11-24 13:14:05 +00001724 hFile = CreateFileA(
1725 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001726 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001727 0, /* share mode */
1728 NULL, /* security attributes */
1729 OPEN_EXISTING,
1730 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001731 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1732 Because of this, calls like GetFinalPathNameByHandle will return
1733 the symlink path agin and not the actual final path. */
1734 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1735 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001736 NULL);
1737
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001738 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001739 /* Either the target doesn't exist, or we don't have access to
1740 get a handle to it. If the former, we need to return an error.
1741 If the latter, we can use attributes_from_dir. */
1742 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001743 return -1;
1744 /* Could not get attributes on open file. Fall back to
1745 reading the directory. */
1746 if (!attributes_from_dir(path, &info, &reparse_tag))
1747 /* Very strange. This should not fail now */
1748 return -1;
1749 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1750 if (traverse) {
1751 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001752 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001753 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001754 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001755 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001756 } else {
1757 if (!GetFileInformationByHandle(hFile, &info)) {
1758 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001759 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001760 }
1761 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001762 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1763 return -1;
1764
1765 /* Close the outer open file handle now that we're about to
1766 reopen it with different flags. */
1767 if (!CloseHandle(hFile))
1768 return -1;
1769
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001770 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001771 /* In order to call GetFinalPathNameByHandle we need to open
1772 the file without the reparse handling flag set. */
1773 hFile2 = CreateFileA(
1774 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1775 NULL, OPEN_EXISTING,
1776 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1777 NULL);
1778 if (hFile2 == INVALID_HANDLE_VALUE)
1779 return -1;
1780
1781 if (!get_target_path(hFile2, &target_path))
1782 return -1;
1783
1784 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001785 free(target_path);
1786 return code;
1787 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001788 } else
1789 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001790 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001791 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001792
1793 /* Set S_IEXEC if it is an .exe, .bat, ... */
1794 dot = strrchr(path, '.');
1795 if (dot) {
1796 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1797 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1798 result->st_mode |= 0111;
1799 }
1800 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001801}
1802
1803static int
Brian Curtind25aef52011-06-13 15:16:04 -05001804win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1805 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001806{
1807 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001808 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001809 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001810 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001811 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001812 const wchar_t *dot;
1813
Brian Curtind25aef52011-06-13 15:16:04 -05001814 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001815 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1816 traverse reparse point. */
1817 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001818 }
1819
Brian Curtinf5e76d02010-11-24 13:14:05 +00001820 hFile = CreateFileW(
1821 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001822 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001823 0, /* share mode */
1824 NULL, /* security attributes */
1825 OPEN_EXISTING,
1826 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001827 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1828 Because of this, calls like GetFinalPathNameByHandle will return
1829 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001830 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001831 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001832 NULL);
1833
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001834 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001835 /* Either the target doesn't exist, or we don't have access to
1836 get a handle to it. If the former, we need to return an error.
1837 If the latter, we can use attributes_from_dir. */
1838 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001839 return -1;
1840 /* Could not get attributes on open file. Fall back to
1841 reading the directory. */
1842 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1843 /* Very strange. This should not fail now */
1844 return -1;
1845 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1846 if (traverse) {
1847 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001848 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001849 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001850 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001851 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001852 } else {
1853 if (!GetFileInformationByHandle(hFile, &info)) {
1854 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001855 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001856 }
1857 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001858 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1859 return -1;
1860
1861 /* Close the outer open file handle now that we're about to
1862 reopen it with different flags. */
1863 if (!CloseHandle(hFile))
1864 return -1;
1865
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001866 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001867 /* In order to call GetFinalPathNameByHandle we need to open
1868 the file without the reparse handling flag set. */
1869 hFile2 = CreateFileW(
1870 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1871 NULL, OPEN_EXISTING,
1872 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1873 NULL);
1874 if (hFile2 == INVALID_HANDLE_VALUE)
1875 return -1;
1876
1877 if (!get_target_path(hFile2, &target_path))
1878 return -1;
1879
1880 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001881 free(target_path);
1882 return code;
1883 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001884 } else
1885 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001886 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001887 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001888
1889 /* Set S_IEXEC if it is an .exe, .bat, ... */
1890 dot = wcsrchr(path, '.');
1891 if (dot) {
1892 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1893 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1894 result->st_mode |= 0111;
1895 }
1896 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001897}
1898
1899static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001900win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001901{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001902 /* Protocol violation: we explicitly clear errno, instead of
1903 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001904 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001905 errno = 0;
1906 return code;
1907}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001908
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001909static int
1910win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1911{
1912 /* Protocol violation: we explicitly clear errno, instead of
1913 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001914 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001915 errno = 0;
1916 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001917}
Brian Curtind25aef52011-06-13 15:16:04 -05001918/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001919
1920 In Posix, stat automatically traverses symlinks and returns the stat
1921 structure for the target. In Windows, the equivalent GetFileAttributes by
1922 default does not traverse symlinks and instead returns attributes for
1923 the symlink.
1924
1925 Therefore, win32_lstat will get the attributes traditionally, and
1926 win32_stat will first explicitly resolve the symlink target and then will
1927 call win32_lstat on that result.
1928
Ezio Melotti4969f702011-03-15 05:59:46 +02001929 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001930
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001931static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001932win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001933{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001934 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001935}
1936
Victor Stinner8c62be82010-05-06 00:08:46 +00001937static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001938win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001939{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001940 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001941}
1942
1943static int
1944win32_stat(const char* path, struct win32_stat *result)
1945{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001946 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001947}
1948
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001949static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001950win32_stat_w(const wchar_t* path, struct win32_stat *result)
1951{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001952 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001953}
1954
1955static int
1956win32_fstat(int file_number, struct win32_stat *result)
1957{
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 BY_HANDLE_FILE_INFORMATION info;
1959 HANDLE h;
1960 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001961
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001962 if (!_PyVerify_fd(file_number))
1963 h = INVALID_HANDLE_VALUE;
1964 else
1965 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001966
Victor Stinner8c62be82010-05-06 00:08:46 +00001967 /* Protocol violation: we explicitly clear errno, instead of
1968 setting it to a POSIX error. Callers should use GetLastError. */
1969 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001970
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 if (h == INVALID_HANDLE_VALUE) {
1972 /* This is really a C library error (invalid file handle).
1973 We set the Win32 error to the closes one matching. */
1974 SetLastError(ERROR_INVALID_HANDLE);
1975 return -1;
1976 }
1977 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001978
Victor Stinner8c62be82010-05-06 00:08:46 +00001979 type = GetFileType(h);
1980 if (type == FILE_TYPE_UNKNOWN) {
1981 DWORD error = GetLastError();
1982 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001983 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001984 }
1985 /* else: valid but unknown file */
1986 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001987
Victor Stinner8c62be82010-05-06 00:08:46 +00001988 if (type != FILE_TYPE_DISK) {
1989 if (type == FILE_TYPE_CHAR)
1990 result->st_mode = _S_IFCHR;
1991 else if (type == FILE_TYPE_PIPE)
1992 result->st_mode = _S_IFIFO;
1993 return 0;
1994 }
1995
1996 if (!GetFileInformationByHandle(h, &info)) {
1997 return -1;
1998 }
1999
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002000 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
2003 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00002004}
2005
2006#endif /* MS_WINDOWS */
2007
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002008PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002009"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002010This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002011 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002012or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2013\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002014Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2015or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002016\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002017See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002018
2019static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002020 {"st_mode", "protection bits"},
2021 {"st_ino", "inode"},
2022 {"st_dev", "device"},
2023 {"st_nlink", "number of hard links"},
2024 {"st_uid", "user ID of owner"},
2025 {"st_gid", "group ID of owner"},
2026 {"st_size", "total size, in bytes"},
2027 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2028 {NULL, "integer time of last access"},
2029 {NULL, "integer time of last modification"},
2030 {NULL, "integer time of last change"},
2031 {"st_atime", "time of last access"},
2032 {"st_mtime", "time of last modification"},
2033 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002034 {"st_atime_ns", "time of last access in nanoseconds"},
2035 {"st_mtime_ns", "time of last modification in nanoseconds"},
2036 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002037#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002039#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002040#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002042#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002043#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002045#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002046#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002047 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002048#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002049#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002051#endif
2052#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002054#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002055 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002056};
2057
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002058#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002059#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002060#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002061#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002062#endif
2063
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002064#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002065#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2066#else
2067#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2068#endif
2069
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002070#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002071#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2072#else
2073#define ST_RDEV_IDX ST_BLOCKS_IDX
2074#endif
2075
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002076#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2077#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2078#else
2079#define ST_FLAGS_IDX ST_RDEV_IDX
2080#endif
2081
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002082#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002083#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002084#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002085#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002086#endif
2087
2088#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2089#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2090#else
2091#define ST_BIRTHTIME_IDX ST_GEN_IDX
2092#endif
2093
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002094static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 "stat_result", /* name */
2096 stat_result__doc__, /* doc */
2097 stat_result_fields,
2098 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002099};
2100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002101PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002102"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2103This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002104 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002105or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002106\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002107See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002108
2109static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 {"f_bsize", },
2111 {"f_frsize", },
2112 {"f_blocks", },
2113 {"f_bfree", },
2114 {"f_bavail", },
2115 {"f_files", },
2116 {"f_ffree", },
2117 {"f_favail", },
2118 {"f_flag", },
2119 {"f_namemax",},
2120 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002121};
2122
2123static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002124 "statvfs_result", /* name */
2125 statvfs_result__doc__, /* doc */
2126 statvfs_result_fields,
2127 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002128};
2129
Ross Lagerwall7807c352011-03-17 20:20:30 +02002130#if defined(HAVE_WAITID) && !defined(__APPLE__)
2131PyDoc_STRVAR(waitid_result__doc__,
2132"waitid_result: Result from waitid.\n\n\
2133This object may be accessed either as a tuple of\n\
2134 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2135or via the attributes si_pid, si_uid, and so on.\n\
2136\n\
2137See os.waitid for more information.");
2138
2139static PyStructSequence_Field waitid_result_fields[] = {
2140 {"si_pid", },
2141 {"si_uid", },
2142 {"si_signo", },
2143 {"si_status", },
2144 {"si_code", },
2145 {0}
2146};
2147
2148static PyStructSequence_Desc waitid_result_desc = {
2149 "waitid_result", /* name */
2150 waitid_result__doc__, /* doc */
2151 waitid_result_fields,
2152 5
2153};
2154static PyTypeObject WaitidResultType;
2155#endif
2156
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002157static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002158static PyTypeObject StatResultType;
2159static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002160#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002161static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002162#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002163static newfunc structseq_new;
2164
2165static PyObject *
2166statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2167{
Victor Stinner8c62be82010-05-06 00:08:46 +00002168 PyStructSequence *result;
2169 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002170
Victor Stinner8c62be82010-05-06 00:08:46 +00002171 result = (PyStructSequence*)structseq_new(type, args, kwds);
2172 if (!result)
2173 return NULL;
2174 /* If we have been initialized from a tuple,
2175 st_?time might be set to None. Initialize it
2176 from the int slots. */
2177 for (i = 7; i <= 9; i++) {
2178 if (result->ob_item[i+3] == Py_None) {
2179 Py_DECREF(Py_None);
2180 Py_INCREF(result->ob_item[i]);
2181 result->ob_item[i+3] = result->ob_item[i];
2182 }
2183 }
2184 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002185}
2186
2187
2188
2189/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002190static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002191
2192PyDoc_STRVAR(stat_float_times__doc__,
2193"stat_float_times([newval]) -> oldval\n\n\
2194Determine whether os.[lf]stat represents time stamps as float objects.\n\
2195If newval is True, future calls to stat() return floats, if it is False,\n\
2196future calls return ints. \n\
2197If newval is omitted, return the current setting.\n");
2198
2199static PyObject*
2200stat_float_times(PyObject* self, PyObject *args)
2201{
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 int newval = -1;
2203 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2204 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002205 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2206 "stat_float_times() is deprecated",
2207 1))
2208 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002209 if (newval == -1)
2210 /* Return old value */
2211 return PyBool_FromLong(_stat_float_times);
2212 _stat_float_times = newval;
2213 Py_INCREF(Py_None);
2214 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002215}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002216
Larry Hastings6fe20b32012-04-19 15:07:49 -07002217static PyObject *billion = NULL;
2218
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002219static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002220fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002221{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002222 PyObject *s = _PyLong_FromTime_t(sec);
2223 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2224 PyObject *s_in_ns = NULL;
2225 PyObject *ns_total = NULL;
2226 PyObject *float_s = NULL;
2227
2228 if (!(s && ns_fractional))
2229 goto exit;
2230
2231 s_in_ns = PyNumber_Multiply(s, billion);
2232 if (!s_in_ns)
2233 goto exit;
2234
2235 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2236 if (!ns_total)
2237 goto exit;
2238
Victor Stinner4195b5c2012-02-08 23:03:19 +01002239 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002240 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2241 if (!float_s)
2242 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002243 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002244 else {
2245 float_s = s;
2246 Py_INCREF(float_s);
2247 }
2248
2249 PyStructSequence_SET_ITEM(v, index, s);
2250 PyStructSequence_SET_ITEM(v, index+3, float_s);
2251 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2252 s = NULL;
2253 float_s = NULL;
2254 ns_total = NULL;
2255exit:
2256 Py_XDECREF(s);
2257 Py_XDECREF(ns_fractional);
2258 Py_XDECREF(s_in_ns);
2259 Py_XDECREF(ns_total);
2260 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002261}
2262
Tim Peters5aa91602002-01-30 05:46:57 +00002263/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002264 (used by posix_stat() and posix_fstat()) */
2265static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002266_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002267{
Victor Stinner8c62be82010-05-06 00:08:46 +00002268 unsigned long ansec, mnsec, cnsec;
2269 PyObject *v = PyStructSequence_New(&StatResultType);
2270 if (v == NULL)
2271 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002272
Victor Stinner8c62be82010-05-06 00:08:46 +00002273 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002274#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002275 PyStructSequence_SET_ITEM(v, 1,
2276 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002277#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002278 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002279#endif
2280#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002281 PyStructSequence_SET_ITEM(v, 2,
2282 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002283#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002284 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002285#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002286 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002287#if defined(MS_WINDOWS)
2288 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2289 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2290#else
2291 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2292 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2293#endif
Fred Drake699f3522000-06-29 21:12:41 +00002294#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002295 PyStructSequence_SET_ITEM(v, 6,
2296 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002297#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002299#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002300
Martin v. Löwis14694662006-02-03 12:54:16 +00002301#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002302 ansec = st->st_atim.tv_nsec;
2303 mnsec = st->st_mtim.tv_nsec;
2304 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002305#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002306 ansec = st->st_atimespec.tv_nsec;
2307 mnsec = st->st_mtimespec.tv_nsec;
2308 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002309#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002310 ansec = st->st_atime_nsec;
2311 mnsec = st->st_mtime_nsec;
2312 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002313#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002314 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002315#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002316 fill_time(v, 7, st->st_atime, ansec);
2317 fill_time(v, 8, st->st_mtime, mnsec);
2318 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002319
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002320#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002321 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2322 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002323#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002324#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002325 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2326 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002327#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002328#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002329 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2330 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002331#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002332#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002333 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2334 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002335#endif
2336#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002337 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002338 PyObject *val;
2339 unsigned long bsec,bnsec;
2340 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002341#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002342 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002343#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002344 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002345#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002346 if (_stat_float_times) {
2347 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2348 } else {
2349 val = PyLong_FromLong((long)bsec);
2350 }
2351 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2352 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002353 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002354#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002355#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002356 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2357 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002358#endif
Fred Drake699f3522000-06-29 21:12:41 +00002359
Victor Stinner8c62be82010-05-06 00:08:46 +00002360 if (PyErr_Occurred()) {
2361 Py_DECREF(v);
2362 return NULL;
2363 }
Fred Drake699f3522000-06-29 21:12:41 +00002364
Victor Stinner8c62be82010-05-06 00:08:46 +00002365 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002366}
2367
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002368/* POSIX methods */
2369
Guido van Rossum94f6f721999-01-06 18:42:14 +00002370
2371static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002372posix_do_stat(char *function_name, path_t *path,
2373 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002374{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002375 STRUCT_STAT st;
2376 int result;
2377
2378#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2379 if (follow_symlinks_specified(function_name, follow_symlinks))
2380 return NULL;
2381#endif
2382
2383 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2384 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2385 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2386 return NULL;
2387
2388 Py_BEGIN_ALLOW_THREADS
2389 if (path->fd != -1)
2390 result = FSTAT(path->fd, &st);
2391 else
2392#ifdef MS_WINDOWS
2393 if (path->wide) {
2394 if (follow_symlinks)
2395 result = win32_stat_w(path->wide, &st);
2396 else
2397 result = win32_lstat_w(path->wide, &st);
2398 }
2399 else
2400#endif
2401#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2402 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2403 result = LSTAT(path->narrow, &st);
2404 else
2405#endif
2406#ifdef HAVE_FSTATAT
2407 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2408 result = fstatat(dir_fd, path->narrow, &st,
2409 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2410 else
2411#endif
2412 result = STAT(path->narrow, &st);
2413 Py_END_ALLOW_THREADS
2414
2415 if (result != 0)
2416 return path_error("stat", path);
2417
2418 return _pystat_fromstructstat(&st);
2419}
2420
2421PyDoc_STRVAR(posix_stat__doc__,
2422"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2423Perform a stat system call on the given path.\n\
2424\n\
2425path may be specified as either a string or as an open file descriptor.\n\
2426\n\
2427If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2428 and path should be relative; path will then be relative to that directory.\n\
2429 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2430 it will raise a NotImplementedError.\n\
2431If follow_symlinks is False, and the last element of the path is a symbolic\n\
2432 link, stat will examine the symbolic link itself instead of the file the\n\
2433 link points to.\n\
2434It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2435 an open file descriptor.");
2436
2437static PyObject *
2438posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2439{
2440 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2441 path_t path;
2442 int dir_fd = DEFAULT_DIR_FD;
2443 int follow_symlinks = 1;
2444 PyObject *return_value;
2445
2446 memset(&path, 0, sizeof(path));
2447 path.allow_fd = 1;
2448 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2449 path_converter, &path,
2450#ifdef HAVE_FSTATAT
2451 dir_fd_converter, &dir_fd,
2452#else
2453 dir_fd_unavailable, &dir_fd,
2454#endif
2455 &follow_symlinks))
2456 return NULL;
2457 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2458 path_cleanup(&path);
2459 return return_value;
2460}
2461
2462PyDoc_STRVAR(posix_lstat__doc__,
2463"lstat(path, *, dir_fd=None) -> stat result\n\n\
2464Like stat(), but do not follow symbolic links.\n\
2465Equivalent to stat(path, follow_symlinks=False).");
2466
2467static PyObject *
2468posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2469{
2470 static char *keywords[] = {"path", "dir_fd", NULL};
2471 path_t path;
2472 int dir_fd = DEFAULT_DIR_FD;
2473 int follow_symlinks = 0;
2474 PyObject *return_value;
2475
2476 memset(&path, 0, sizeof(path));
2477 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2478 path_converter, &path,
2479#ifdef HAVE_FSTATAT
2480 dir_fd_converter, &dir_fd
2481#else
2482 dir_fd_unavailable, &dir_fd
2483#endif
2484 ))
2485 return NULL;
2486 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2487 path_cleanup(&path);
2488 return return_value;
2489}
2490
2491PyDoc_STRVAR(posix_access__doc__,
2492"access(path, mode, *, dir_fd=None, effective_ids=False,\
2493 follow_symlinks=True)\n\n\
2494Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2495False otherwise.\n\
2496\n\
2497If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2498 and path should be relative; path will then be relative to that directory.\n\
2499If effective_ids is True, access will use the effective uid/gid instead of\n\
2500 the real uid/gid.\n\
2501If follow_symlinks is False, and the last element of the path is a symbolic\n\
2502 link, access will examine the symbolic link itself instead of the file the\n\
2503 link points to.\n\
2504dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2505 on your platform. If they are unavailable, using them will raise a\n\
2506 NotImplementedError.\n\
2507\n\
2508Note that most operations will use the effective uid/gid, therefore this\n\
2509 routine can be used in a suid/sgid environment to test if the invoking user\n\
2510 has the specified access to the path.\n\
2511The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2512 of R_OK, W_OK, and X_OK.");
2513
2514static PyObject *
2515posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2516{
2517 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2518 "follow_symlinks", NULL};
2519 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521 int dir_fd = DEFAULT_DIR_FD;
2522 int effective_ids = 0;
2523 int follow_symlinks = 1;
2524 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002525
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002526#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002527 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002528#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002529 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002530#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002531
2532 memset(&path, 0, sizeof(path));
2533 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2534 path_converter, &path, &mode,
2535#ifdef HAVE_FACCESSAT
2536 dir_fd_converter, &dir_fd,
2537#else
2538 dir_fd_unavailable, &dir_fd,
2539#endif
2540 &effective_ids, &follow_symlinks))
2541 return NULL;
2542
2543#ifndef HAVE_FACCESSAT
2544 if (follow_symlinks_specified("access", follow_symlinks))
2545 goto exit;
2546
2547 if (effective_ids) {
2548 argument_unavailable_error("access", "effective_ids");
2549 goto exit;
2550 }
2551#endif
2552
2553#ifdef MS_WINDOWS
2554 Py_BEGIN_ALLOW_THREADS
2555 if (path.wide != NULL)
2556 attr = GetFileAttributesW(path.wide);
2557 else
2558 attr = GetFileAttributesA(path.narrow);
2559 Py_END_ALLOW_THREADS
2560
2561 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002562 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002563 * * we didn't get a -1, and
2564 * * write access wasn't requested,
2565 * * or the file isn't read-only,
2566 * * or it's a directory.
2567 * (Directories cannot be read-only on Windows.)
2568 */
2569 return_value = PyBool_FromLong(
2570 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002571 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 !(attr & FILE_ATTRIBUTE_READONLY) ||
2573 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2574#else
2575
2576 Py_BEGIN_ALLOW_THREADS
2577#ifdef HAVE_FACCESSAT
2578 if ((dir_fd != DEFAULT_DIR_FD) ||
2579 effective_ids ||
2580 !follow_symlinks) {
2581 int flags = 0;
2582 if (!follow_symlinks)
2583 flags |= AT_SYMLINK_NOFOLLOW;
2584 if (effective_ids)
2585 flags |= AT_EACCESS;
2586 result = faccessat(dir_fd, path.narrow, mode, flags);
2587 }
2588 else
2589#endif
2590 result = access(path.narrow, mode);
2591 Py_END_ALLOW_THREADS
2592 return_value = PyBool_FromLong(!result);
2593#endif
2594
2595#ifndef HAVE_FACCESSAT
2596exit:
2597#endif
2598 path_cleanup(&path);
2599 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002600}
2601
Guido van Rossumd371ff11999-01-25 16:12:23 +00002602#ifndef F_OK
2603#define F_OK 0
2604#endif
2605#ifndef R_OK
2606#define R_OK 4
2607#endif
2608#ifndef W_OK
2609#define W_OK 2
2610#endif
2611#ifndef X_OK
2612#define X_OK 1
2613#endif
2614
2615#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002616PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002617"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002618Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002619
2620static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002621posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002622{
Victor Stinner8c62be82010-05-06 00:08:46 +00002623 int id;
2624 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002625
Victor Stinner8c62be82010-05-06 00:08:46 +00002626 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2627 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002628
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002629#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002630 /* file descriptor 0 only, the default input device (stdin) */
2631 if (id == 0) {
2632 ret = ttyname();
2633 }
2634 else {
2635 ret = NULL;
2636 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002637#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002638 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002639#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002640 if (ret == NULL)
2641 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002642 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002643}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002644#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002645
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002646#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002647PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002648"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002649Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002650
2651static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002652posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002653{
Victor Stinner8c62be82010-05-06 00:08:46 +00002654 char *ret;
2655 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002656
Greg Wardb48bc172000-03-01 21:51:56 +00002657#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002658 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002659#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002661#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002662 if (ret == NULL)
2663 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002664 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002665}
2666#endif
2667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002668PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002669"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002670Change the current working directory to the specified path.\n\
2671\n\
2672path may always be specified as a string.\n\
2673On some platforms, path may also be specified as an open file descriptor.\n\
2674 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002675
Barry Warsaw53699e91996-12-10 23:23:01 +00002676static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002677posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002678{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002679 path_t path;
2680 int result;
2681 PyObject *return_value = NULL;
2682 static char *keywords[] = {"path", NULL};
2683
2684 memset(&path, 0, sizeof(path));
2685#ifdef HAVE_FCHDIR
2686 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002687#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002688 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2689 path_converter, &path
2690 ))
2691 return NULL;
2692
2693 Py_BEGIN_ALLOW_THREADS
2694#ifdef MS_WINDOWS
2695 if (path.wide)
2696 result = win32_wchdir(path.wide);
2697 else
2698 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002699 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002700#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2701 result = _chdir2(path.narrow);
2702#else
2703#ifdef HAVE_FCHDIR
2704 if (path.fd != -1)
2705 result = fchdir(path.fd);
2706 else
2707#endif
2708 result = chdir(path.narrow);
2709#endif
2710 Py_END_ALLOW_THREADS
2711
2712 if (result) {
2713 return_value = path_error("chdir", &path);
2714 goto exit;
2715 }
2716
2717 return_value = Py_None;
2718 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002719
Larry Hastings9cf065c2012-06-22 16:30:09 -07002720exit:
2721 path_cleanup(&path);
2722 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002723}
2724
Fred Drake4d1e64b2002-04-15 19:40:07 +00002725#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002726PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002727"fchdir(fd)\n\n\
2728Change to the directory of the given file descriptor. fd must be\n\
2729opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002730
2731static PyObject *
2732posix_fchdir(PyObject *self, PyObject *fdobj)
2733{
Victor Stinner8c62be82010-05-06 00:08:46 +00002734 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002735}
2736#endif /* HAVE_FCHDIR */
2737
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2741Change the access permissions of a file.\n\
2742\n\
2743path may always be specified as a string.\n\
2744On some platforms, path may also be specified as an open file descriptor.\n\
2745 If this functionality is unavailable, using it raises an exception.\n\
2746If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2747 and path should be relative; path will then be relative to that directory.\n\
2748If follow_symlinks is False, and the last element of the path is a symbolic\n\
2749 link, chmod will modify the symbolic link itself instead of the file the\n\
2750 link points to.\n\
2751It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2752 an open file descriptor.\n\
2753dir_fd and follow_symlinks may not be implemented on your platform.\n\
2754 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002755
Barry Warsaw53699e91996-12-10 23:23:01 +00002756static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002757posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002758{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002759 path_t path;
2760 int mode;
2761 int dir_fd = DEFAULT_DIR_FD;
2762 int follow_symlinks = 1;
2763 int result;
2764 PyObject *return_value = NULL;
2765 static char *keywords[] = {"path", "mode", "dir_fd",
2766 "follow_symlinks", NULL};
2767
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002768#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002769 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002770#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002771
Larry Hastings9cf065c2012-06-22 16:30:09 -07002772#ifdef HAVE_FCHMODAT
2773 int fchmodat_nofollow_unsupported = 0;
2774#endif
2775
2776 memset(&path, 0, sizeof(path));
2777#ifdef HAVE_FCHMOD
2778 path.allow_fd = 1;
2779#endif
2780 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2781 path_converter, &path,
2782 &mode,
2783#ifdef HAVE_FCHMODAT
2784 dir_fd_converter, &dir_fd,
2785#else
2786 dir_fd_unavailable, &dir_fd,
2787#endif
2788 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002789 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790
2791#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2792 if (follow_symlinks_specified("chmod", follow_symlinks))
2793 goto exit;
2794#endif
2795
2796#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002797 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798 if (path.wide)
2799 attr = GetFileAttributesW(path.wide);
2800 else
2801 attr = GetFileAttributesA(path.narrow);
2802 if (attr == 0xFFFFFFFF)
2803 result = 0;
2804 else {
2805 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002806 attr &= ~FILE_ATTRIBUTE_READONLY;
2807 else
2808 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809 if (path.wide)
2810 result = SetFileAttributesW(path.wide, attr);
2811 else
2812 result = SetFileAttributesA(path.narrow, attr);
2813 }
2814 Py_END_ALLOW_THREADS
2815
2816 if (!result) {
2817 return_value = win32_error_object("chmod", path.object);
2818 goto exit;
2819 }
2820#else /* MS_WINDOWS */
2821 Py_BEGIN_ALLOW_THREADS
2822#ifdef HAVE_FCHMOD
2823 if (path.fd != -1)
2824 result = fchmod(path.fd, mode);
2825 else
2826#endif
2827#ifdef HAVE_LCHMOD
2828 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2829 result = lchmod(path.narrow, mode);
2830 else
2831#endif
2832#ifdef HAVE_FCHMODAT
2833 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2834 /*
2835 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2836 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002837 * and then says it isn't implemented yet.
2838 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839 *
2840 * Once it is supported, os.chmod will automatically
2841 * support dir_fd and follow_symlinks=False. (Hopefully.)
2842 * Until then, we need to be careful what exception we raise.
2843 */
2844 result = fchmodat(dir_fd, path.narrow, mode,
2845 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2846 /*
2847 * But wait! We can't throw the exception without allowing threads,
2848 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2849 */
2850 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002851 result &&
2852 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2853 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002854 }
2855 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002856#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002857 result = chmod(path.narrow, mode);
2858 Py_END_ALLOW_THREADS
2859
2860 if (result) {
2861#ifdef HAVE_FCHMODAT
2862 if (fchmodat_nofollow_unsupported) {
2863 if (dir_fd != DEFAULT_DIR_FD)
2864 dir_fd_and_follow_symlinks_invalid("chmod",
2865 dir_fd, follow_symlinks);
2866 else
2867 follow_symlinks_specified("chmod", follow_symlinks);
2868 }
2869 else
2870#endif
2871 return_value = path_error("chmod", &path);
2872 goto exit;
2873 }
2874#endif
2875
2876 Py_INCREF(Py_None);
2877 return_value = Py_None;
2878exit:
2879 path_cleanup(&path);
2880 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002881}
2882
Larry Hastings9cf065c2012-06-22 16:30:09 -07002883
Christian Heimes4e30a842007-11-30 22:12:06 +00002884#ifdef HAVE_FCHMOD
2885PyDoc_STRVAR(posix_fchmod__doc__,
2886"fchmod(fd, mode)\n\n\
2887Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002888descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002889
2890static PyObject *
2891posix_fchmod(PyObject *self, PyObject *args)
2892{
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 int fd, mode, res;
2894 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2895 return NULL;
2896 Py_BEGIN_ALLOW_THREADS
2897 res = fchmod(fd, mode);
2898 Py_END_ALLOW_THREADS
2899 if (res < 0)
2900 return posix_error();
2901 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002902}
2903#endif /* HAVE_FCHMOD */
2904
2905#ifdef HAVE_LCHMOD
2906PyDoc_STRVAR(posix_lchmod__doc__,
2907"lchmod(path, mode)\n\n\
2908Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002909affects the link itself rather than the target.\n\
2910Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002911
2912static PyObject *
2913posix_lchmod(PyObject *self, PyObject *args)
2914{
Victor Stinner8c62be82010-05-06 00:08:46 +00002915 PyObject *opath;
2916 char *path;
2917 int i;
2918 int res;
2919 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2920 &opath, &i))
2921 return NULL;
2922 path = PyBytes_AsString(opath);
2923 Py_BEGIN_ALLOW_THREADS
2924 res = lchmod(path, i);
2925 Py_END_ALLOW_THREADS
2926 if (res < 0)
2927 return posix_error_with_allocated_filename(opath);
2928 Py_DECREF(opath);
2929 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002930}
2931#endif /* HAVE_LCHMOD */
2932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002933
Thomas Wouterscf297e42007-02-23 15:07:44 +00002934#ifdef HAVE_CHFLAGS
2935PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002936"chflags(path, flags, *, follow_symlinks=True)\n\n\
2937Set file flags.\n\
2938\n\
2939If follow_symlinks is False, and the last element of the path is a symbolic\n\
2940 link, chflags will change flags on the symbolic link itself instead of the\n\
2941 file the link points to.\n\
2942follow_symlinks may not be implemented on your platform. If it is\n\
2943unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002944
2945static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002946posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002947{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002949 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002950 int follow_symlinks = 1;
2951 int result;
2952 PyObject *return_value;
2953 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2954
2955 memset(&path, 0, sizeof(path));
2956 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2957 path_converter, &path,
2958 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002959 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002960
2961#ifndef HAVE_LCHFLAGS
2962 if (follow_symlinks_specified("chflags", follow_symlinks))
2963 goto exit;
2964#endif
2965
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002967#ifdef HAVE_LCHFLAGS
2968 if (!follow_symlinks)
2969 result = lchflags(path.narrow, flags);
2970 else
2971#endif
2972 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002973 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002974
2975 if (result) {
2976 return_value = path_posix_error("chflags", &path);
2977 goto exit;
2978 }
2979
2980 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002981 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002982
2983exit:
2984 path_cleanup(&path);
2985 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002986}
2987#endif /* HAVE_CHFLAGS */
2988
2989#ifdef HAVE_LCHFLAGS
2990PyDoc_STRVAR(posix_lchflags__doc__,
2991"lchflags(path, flags)\n\n\
2992Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002993This function will not follow symbolic links.\n\
2994Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002995
2996static PyObject *
2997posix_lchflags(PyObject *self, PyObject *args)
2998{
Victor Stinner8c62be82010-05-06 00:08:46 +00002999 PyObject *opath;
3000 char *path;
3001 unsigned long flags;
3002 int res;
3003 if (!PyArg_ParseTuple(args, "O&k:lchflags",
3004 PyUnicode_FSConverter, &opath, &flags))
3005 return NULL;
3006 path = PyBytes_AsString(opath);
3007 Py_BEGIN_ALLOW_THREADS
3008 res = lchflags(path, flags);
3009 Py_END_ALLOW_THREADS
3010 if (res < 0)
3011 return posix_error_with_allocated_filename(opath);
3012 Py_DECREF(opath);
3013 Py_INCREF(Py_None);
3014 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003015}
3016#endif /* HAVE_LCHFLAGS */
3017
Martin v. Löwis244edc82001-10-04 22:44:26 +00003018#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003019PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003020"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003021Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003022
3023static PyObject *
3024posix_chroot(PyObject *self, PyObject *args)
3025{
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003027}
3028#endif
3029
Guido van Rossum21142a01999-01-08 21:05:37 +00003030#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003032"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003033force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003034
3035static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003036posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003037{
Stefan Krah0e803b32010-11-26 16:16:47 +00003038 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003039}
3040#endif /* HAVE_FSYNC */
3041
Ross Lagerwall7807c352011-03-17 20:20:30 +02003042#ifdef HAVE_SYNC
3043PyDoc_STRVAR(posix_sync__doc__,
3044"sync()\n\n\
3045Force write of everything to disk.");
3046
3047static PyObject *
3048posix_sync(PyObject *self, PyObject *noargs)
3049{
3050 Py_BEGIN_ALLOW_THREADS
3051 sync();
3052 Py_END_ALLOW_THREADS
3053 Py_RETURN_NONE;
3054}
3055#endif
3056
Guido van Rossum21142a01999-01-08 21:05:37 +00003057#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003058
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003059#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003060extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3061#endif
3062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003063PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003064"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003065force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003066 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003067
3068static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003069posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003070{
Stefan Krah0e803b32010-11-26 16:16:47 +00003071 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003072}
3073#endif /* HAVE_FDATASYNC */
3074
3075
Fredrik Lundh10723342000-07-10 16:38:09 +00003076#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003077PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003078"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3079Change the owner and group id of path to the numeric uid and gid.\n\
3080\n\
3081path may always be specified as a string.\n\
3082On some platforms, path may also be specified as an open file descriptor.\n\
3083 If this functionality is unavailable, using it raises an exception.\n\
3084If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3085 and path should be relative; path will then be relative to that directory.\n\
3086If follow_symlinks is False, and the last element of the path is a symbolic\n\
3087 link, chown will modify the symbolic link itself instead of the file the\n\
3088 link points to.\n\
3089It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3090 an open file descriptor.\n\
3091dir_fd and follow_symlinks may not be implemented on your platform.\n\
3092 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003093
Barry Warsaw53699e91996-12-10 23:23:01 +00003094static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003095posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003096{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003098 uid_t uid;
3099 gid_t gid;
3100 int dir_fd = DEFAULT_DIR_FD;
3101 int follow_symlinks = 1;
3102 int result;
3103 PyObject *return_value = NULL;
3104 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3105 "follow_symlinks", NULL};
3106
3107 memset(&path, 0, sizeof(path));
3108#ifdef HAVE_FCHOWN
3109 path.allow_fd = 1;
3110#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003111 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003112 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003113 _Py_Uid_Converter, &uid,
3114 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003115#ifdef HAVE_FCHOWNAT
3116 dir_fd_converter, &dir_fd,
3117#else
3118 dir_fd_unavailable, &dir_fd,
3119#endif
3120 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003121 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003122
3123#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3124 if (follow_symlinks_specified("chown", follow_symlinks))
3125 goto exit;
3126#endif
3127 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3128 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3129 goto exit;
3130
3131#ifdef __APPLE__
3132 /*
3133 * This is for Mac OS X 10.3, which doesn't have lchown.
3134 * (But we still have an lchown symbol because of weak-linking.)
3135 * It doesn't have fchownat either. So there's no possibility
3136 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003137 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003138 if ((!follow_symlinks) && (lchown == NULL)) {
3139 follow_symlinks_specified("chown", follow_symlinks);
3140 goto exit;
3141 }
3142#endif
3143
Victor Stinner8c62be82010-05-06 00:08:46 +00003144 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003145#ifdef HAVE_FCHOWN
3146 if (path.fd != -1)
3147 result = fchown(path.fd, uid, gid);
3148 else
3149#endif
3150#ifdef HAVE_LCHOWN
3151 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3152 result = lchown(path.narrow, uid, gid);
3153 else
3154#endif
3155#ifdef HAVE_FCHOWNAT
3156 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3157 result = fchownat(dir_fd, path.narrow, uid, gid,
3158 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3159 else
3160#endif
3161 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003162 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003163
3164 if (result) {
3165 return_value = path_posix_error("chown", &path);
3166 goto exit;
3167 }
3168
3169 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003170 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003171
3172exit:
3173 path_cleanup(&path);
3174 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003175}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003176#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003177
Christian Heimes4e30a842007-11-30 22:12:06 +00003178#ifdef HAVE_FCHOWN
3179PyDoc_STRVAR(posix_fchown__doc__,
3180"fchown(fd, uid, gid)\n\n\
3181Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003183
3184static PyObject *
3185posix_fchown(PyObject *self, PyObject *args)
3186{
Victor Stinner8c62be82010-05-06 00:08:46 +00003187 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003188 uid_t uid;
3189 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003190 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003191 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3192 _Py_Uid_Converter, &uid,
3193 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003194 return NULL;
3195 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003196 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 Py_END_ALLOW_THREADS
3198 if (res < 0)
3199 return posix_error();
3200 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003201}
3202#endif /* HAVE_FCHOWN */
3203
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003204#ifdef HAVE_LCHOWN
3205PyDoc_STRVAR(posix_lchown__doc__,
3206"lchown(path, uid, gid)\n\n\
3207Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003208This function will not follow symbolic links.\n\
3209Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003210
3211static PyObject *
3212posix_lchown(PyObject *self, PyObject *args)
3213{
Victor Stinner8c62be82010-05-06 00:08:46 +00003214 PyObject *opath;
3215 char *path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003216 uid_t uid;
3217 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003218 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003219 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner8c62be82010-05-06 00:08:46 +00003220 PyUnicode_FSConverter, &opath,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003221 _Py_Uid_Converter, &uid,
3222 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 return NULL;
3224 path = PyBytes_AsString(opath);
3225 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003226 res = lchown(path, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003227 Py_END_ALLOW_THREADS
3228 if (res < 0)
3229 return posix_error_with_allocated_filename(opath);
3230 Py_DECREF(opath);
3231 Py_INCREF(Py_None);
3232 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003233}
3234#endif /* HAVE_LCHOWN */
3235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003236
Guido van Rossum36bc6801995-06-14 22:54:23 +00003237#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003238static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003239posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003240{
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 char buf[1026];
3242 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003243
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003244#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003245 if (!use_bytes) {
3246 wchar_t wbuf[1026];
3247 wchar_t *wbuf2 = wbuf;
3248 PyObject *resobj;
3249 DWORD len;
3250 Py_BEGIN_ALLOW_THREADS
3251 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3252 /* If the buffer is large enough, len does not include the
3253 terminating \0. If the buffer is too small, len includes
3254 the space needed for the terminator. */
3255 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3256 wbuf2 = malloc(len * sizeof(wchar_t));
3257 if (wbuf2)
3258 len = GetCurrentDirectoryW(len, wbuf2);
3259 }
3260 Py_END_ALLOW_THREADS
3261 if (!wbuf2) {
3262 PyErr_NoMemory();
3263 return NULL;
3264 }
3265 if (!len) {
3266 if (wbuf2 != wbuf) free(wbuf2);
3267 return win32_error("getcwdu", NULL);
3268 }
3269 resobj = PyUnicode_FromWideChar(wbuf2, len);
3270 if (wbuf2 != wbuf) free(wbuf2);
3271 return resobj;
3272 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003273
3274 if (win32_warn_bytes_api())
3275 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003276#endif
3277
Victor Stinner8c62be82010-05-06 00:08:46 +00003278 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003279#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003281#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003283#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 Py_END_ALLOW_THREADS
3285 if (res == NULL)
3286 return posix_error();
3287 if (use_bytes)
3288 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003289 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003290}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003291
3292PyDoc_STRVAR(posix_getcwd__doc__,
3293"getcwd() -> path\n\n\
3294Return a unicode string representing the current working directory.");
3295
3296static PyObject *
3297posix_getcwd_unicode(PyObject *self)
3298{
3299 return posix_getcwd(0);
3300}
3301
3302PyDoc_STRVAR(posix_getcwdb__doc__,
3303"getcwdb() -> path\n\n\
3304Return a bytes string representing the current working directory.");
3305
3306static PyObject *
3307posix_getcwd_bytes(PyObject *self)
3308{
3309 return posix_getcwd(1);
3310}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003311#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003312
Larry Hastings9cf065c2012-06-22 16:30:09 -07003313#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3314#define HAVE_LINK 1
3315#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003316
Guido van Rossumb6775db1994-08-01 11:34:53 +00003317#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003318PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003319"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3320Create a hard link to a file.\n\
3321\n\
3322If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3323 descriptor open to a directory, and the respective path string (src or dst)\n\
3324 should be relative; the path will then be relative to that directory.\n\
3325If follow_symlinks is False, and the last element of src is a symbolic\n\
3326 link, link will create a link to the symbolic link itself instead of the\n\
3327 file the link points to.\n\
3328src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3329 platform. If they are unavailable, using them will raise a\n\
3330 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003331
Barry Warsaw53699e91996-12-10 23:23:01 +00003332static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003334{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003335 path_t src, dst;
3336 int src_dir_fd = DEFAULT_DIR_FD;
3337 int dst_dir_fd = DEFAULT_DIR_FD;
3338 int follow_symlinks = 1;
3339 PyObject *return_value = NULL;
3340 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3341 "follow_symlinks", NULL};
3342#ifdef MS_WINDOWS
3343 BOOL result;
3344#else
3345 int result;
3346#endif
3347
3348 memset(&src, 0, sizeof(src));
3349 memset(&dst, 0, sizeof(dst));
3350 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3351 path_converter, &src,
3352 path_converter, &dst,
3353 dir_fd_converter, &src_dir_fd,
3354 dir_fd_converter, &dst_dir_fd,
3355 &follow_symlinks))
3356 return NULL;
3357
3358#ifndef HAVE_LINKAT
3359 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3360 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3361 goto exit;
3362 }
3363#endif
3364
3365 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3366 PyErr_SetString(PyExc_NotImplementedError,
3367 "link: src and dst must be the same type");
3368 goto exit;
3369 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003370
Brian Curtin1b9df392010-11-24 20:24:31 +00003371#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003372 Py_BEGIN_ALLOW_THREADS
3373 if (src.wide)
3374 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3375 else
3376 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3377 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003378
Larry Hastings9cf065c2012-06-22 16:30:09 -07003379 if (!result) {
3380 return_value = win32_error_object("link", dst.object);
3381 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003382 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383#else
3384 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003385#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3387 (dst_dir_fd != DEFAULT_DIR_FD) ||
3388 (!follow_symlinks))
3389 result = linkat(src_dir_fd, src.narrow,
3390 dst_dir_fd, dst.narrow,
3391 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3392 else
3393#endif
3394 result = link(src.narrow, dst.narrow);
3395 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003396
Larry Hastings9cf065c2012-06-22 16:30:09 -07003397 if (result) {
3398 return_value = path_error("link", &dst);
3399 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003400 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003401#endif
3402
3403 return_value = Py_None;
3404 Py_INCREF(Py_None);
3405
3406exit:
3407 path_cleanup(&src);
3408 path_cleanup(&dst);
3409 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003410}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411#endif
3412
Brian Curtin1b9df392010-11-24 20:24:31 +00003413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003414
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003415PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003416"listdir(path='.') -> list_of_filenames\n\n\
3417Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003418The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419entries '.' and '..' even if they are present in the directory.\n\
3420\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003421path can be specified as either str or bytes. If path is bytes,\n\
3422 the filenames returned will also be bytes; in all other circumstances\n\
3423 the filenames returned will be str.\n\
3424On some platforms, path may also be specified as an open file descriptor;\n\
3425 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003427
Barry Warsaw53699e91996-12-10 23:23:01 +00003428static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003430{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431 path_t path;
3432 PyObject *list = NULL;
3433 static char *keywords[] = {"path", NULL};
3434 int fd = -1;
3435
3436#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3437 PyObject *v;
3438 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3439 BOOL result;
3440 WIN32_FIND_DATA FileData;
3441 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3442 char *bufptr = namebuf;
3443 /* only claim to have space for MAX_PATH */
3444 Py_ssize_t len = sizeof(namebuf)-5;
3445 PyObject *po = NULL;
3446 wchar_t *wnamebuf = NULL;
3447#elif defined(PYOS_OS2)
3448#ifndef MAX_PATH
3449#define MAX_PATH CCHMAXPATH
3450#endif
3451 char *pt;
3452 PyObject *v;
3453 char namebuf[MAX_PATH+5];
3454 HDIR hdir = 1;
3455 ULONG srchcnt = 1;
3456 FILEFINDBUF3 ep;
3457 APIRET rc;
3458#else
3459 PyObject *v;
3460 DIR *dirp = NULL;
3461 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003462 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463#endif
3464
3465 memset(&path, 0, sizeof(path));
3466 path.nullable = 1;
3467#ifdef HAVE_FDOPENDIR
3468 path.allow_fd = 1;
3469 path.fd = -1;
3470#endif
3471 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3472 path_converter, &path
3473 ))
3474 return NULL;
3475
Victor Stinner8c62be82010-05-06 00:08:46 +00003476 /* XXX Should redo this putting the (now four) versions of opendir
3477 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003478#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003480 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003482
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003484 po_wchars = L".";
3485 len = 1;
3486 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 po_wchars = path.wide;
3488 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003489 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003490 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3492 if (!wnamebuf) {
3493 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003494 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003496 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003498 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003499 if (wch != L'/' && wch != L'\\' && wch != L':')
3500 wnamebuf[len++] = L'\\';
3501 wcscpy(wnamebuf + len, L"*.*");
3502 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503 if ((list = PyList_New(0)) == NULL) {
3504 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003505 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003506 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003508 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 if (hFindFile == INVALID_HANDLE_VALUE) {
3510 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511 if (error == ERROR_FILE_NOT_FOUND)
3512 goto exit;
3513 Py_DECREF(list);
3514 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003515 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 }
3518 do {
3519 /* Skip over . and .. */
3520 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3521 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 v = PyUnicode_FromWideChar(wFileData.cFileName,
3523 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 Py_DECREF(list);
3526 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 break;
3528 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003530 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 Py_DECREF(list);
3532 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003533 break;
3534 }
3535 Py_DECREF(v);
3536 }
3537 Py_BEGIN_ALLOW_THREADS
3538 result = FindNextFileW(hFindFile, &wFileData);
3539 Py_END_ALLOW_THREADS
3540 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3541 it got to the end of the directory. */
3542 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 Py_DECREF(list);
3544 list = win32_error_unicode("FindNextFileW", wnamebuf);
3545 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 }
3547 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003548
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 strcpy(namebuf, path.narrow);
3552 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 if (len > 0) {
3554 char ch = namebuf[len-1];
3555 if (ch != SEP && ch != ALTSEP && ch != ':')
3556 namebuf[len++] = '/';
3557 strcpy(namebuf + len, "*.*");
3558 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003559
Larry Hastings9cf065c2012-06-22 16:30:09 -07003560 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003562
Antoine Pitroub73caab2010-08-09 23:39:31 +00003563 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003565 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003566 if (hFindFile == INVALID_HANDLE_VALUE) {
3567 int error = GetLastError();
3568 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 goto exit;
3570 Py_DECREF(list);
3571 list = win32_error("FindFirstFile", namebuf);
3572 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 }
3574 do {
3575 /* Skip over . and .. */
3576 if (strcmp(FileData.cFileName, ".") != 0 &&
3577 strcmp(FileData.cFileName, "..") != 0) {
3578 v = PyBytes_FromString(FileData.cFileName);
3579 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 Py_DECREF(list);
3581 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 break;
3583 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003584 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003586 Py_DECREF(list);
3587 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 break;
3589 }
3590 Py_DECREF(v);
3591 }
3592 Py_BEGIN_ALLOW_THREADS
3593 result = FindNextFile(hFindFile, &FileData);
3594 Py_END_ALLOW_THREADS
3595 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3596 it got to the end of the directory. */
3597 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 Py_DECREF(list);
3599 list = win32_error("FindNextFile", namebuf);
3600 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 }
3602 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003603
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604exit:
3605 if (hFindFile != INVALID_HANDLE_VALUE) {
3606 if (FindClose(hFindFile) == FALSE) {
3607 if (list != NULL) {
3608 Py_DECREF(list);
3609 list = win32_error_object("FindClose", path.object);
3610 }
3611 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003613 if (wnamebuf)
3614 free(wnamebuf);
3615 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003616
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003618
Tim Peters0bb44a42000-09-15 07:44:49 +00003619#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003621 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003622 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003623 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003625 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003626 if (*pt == ALTSEP)
3627 *pt = SEP;
3628 if (namebuf[len-1] != SEP)
3629 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003630 strcpy(namebuf + len, "*.*");
3631
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 if ((list = PyList_New(0)) == NULL) {
3633 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003634 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003635
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003636 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3637 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003638 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003639 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3640 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3641 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003642
3643 if (rc != NO_ERROR) {
3644 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 Py_DECREF(list);
3646 list = posix_error_with_filename(path.narrow);
3647 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003648 }
3649
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003650 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003651 do {
3652 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003653 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003654 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003655
3656 strcpy(namebuf, ep.achName);
3657
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003658 /* Leave Case of Name Alone -- In Native Form */
3659 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003660
Christian Heimes72b710a2008-05-26 13:28:38 +00003661 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003662 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 Py_DECREF(list);
3664 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003665 break;
3666 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003668 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003669 Py_DECREF(list);
3670 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003671 break;
3672 }
3673 Py_DECREF(v);
3674 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3675 }
3676
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677exit:
3678 path_cleanup(&path);
3679
3680 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003681#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003682
Victor Stinner8c62be82010-05-06 00:08:46 +00003683 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003684#ifdef HAVE_FDOPENDIR
3685 if (path.fd != -1) {
3686 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003687 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003689 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690
3691 if (fd == -1) {
3692 list = posix_error();
3693 goto exit;
3694 }
3695
Larry Hastingsfdaea062012-06-25 04:42:23 -07003696 return_str = 1;
3697
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 Py_BEGIN_ALLOW_THREADS
3699 dirp = fdopendir(fd);
3700 Py_END_ALLOW_THREADS
3701 }
3702 else
3703#endif
3704 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003705 char *name;
3706 if (path.narrow) {
3707 name = path.narrow;
3708 /* only return bytes if they specified a bytes object */
3709 return_str = !(PyBytes_Check(path.object));
3710 }
3711 else {
3712 name = ".";
3713 return_str = 1;
3714 }
3715
Larry Hastings9cf065c2012-06-22 16:30:09 -07003716 Py_BEGIN_ALLOW_THREADS
3717 dirp = opendir(name);
3718 Py_END_ALLOW_THREADS
3719 }
3720
3721 if (dirp == NULL) {
3722 list = path_error("listdir", &path);
3723 goto exit;
3724 }
3725 if ((list = PyList_New(0)) == NULL) {
3726 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 }
3728 for (;;) {
3729 errno = 0;
3730 Py_BEGIN_ALLOW_THREADS
3731 ep = readdir(dirp);
3732 Py_END_ALLOW_THREADS
3733 if (ep == NULL) {
3734 if (errno == 0) {
3735 break;
3736 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003737 Py_DECREF(list);
3738 list = path_error("listdir", &path);
3739 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003740 }
3741 }
3742 if (ep->d_name[0] == '.' &&
3743 (NAMLEN(ep) == 1 ||
3744 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3745 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003746 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003747 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3748 else
3749 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003750 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003751 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 break;
3753 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003754 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003755 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003756 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003757 break;
3758 }
3759 Py_DECREF(v);
3760 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003761
Larry Hastings9cf065c2012-06-22 16:30:09 -07003762exit:
3763 if (dirp != NULL) {
3764 Py_BEGIN_ALLOW_THREADS
3765 if (fd > -1)
3766 rewinddir(dirp);
3767 closedir(dirp);
3768 Py_END_ALLOW_THREADS
3769 }
3770
3771 path_cleanup(&path);
3772
3773 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003774
Tim Peters0bb44a42000-09-15 07:44:49 +00003775#endif /* which OS */
3776} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003777
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003778#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003779/* A helper function for abspath on win32 */
3780static PyObject *
3781posix__getfullpathname(PyObject *self, PyObject *args)
3782{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003783 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 char outbuf[MAX_PATH*2];
3785 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003786 PyObject *po;
3787
3788 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3789 {
3790 wchar_t *wpath;
3791 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3792 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003793 DWORD result;
3794 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003795
3796 wpath = PyUnicode_AsUnicode(po);
3797 if (wpath == NULL)
3798 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003800 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003802 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003803 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003804 if (!woutbufp)
3805 return PyErr_NoMemory();
3806 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3807 }
3808 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003809 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003810 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003811 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003812 if (woutbufp != woutbuf)
3813 free(woutbufp);
3814 return v;
3815 }
3816 /* Drop the argument parsing error as narrow strings
3817 are also valid. */
3818 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003819
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003820 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3821 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003822 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003823 if (win32_warn_bytes_api())
3824 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003825 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003826 outbuf, &temp)) {
3827 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003828 return NULL;
3829 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003830 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3831 return PyUnicode_Decode(outbuf, strlen(outbuf),
3832 Py_FileSystemDefaultEncoding, NULL);
3833 }
3834 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003835} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003836
Brian Curtind25aef52011-06-13 15:16:04 -05003837
Brian Curtinf5e76d02010-11-24 13:14:05 +00003838
Brian Curtind40e6f72010-07-08 21:39:08 +00003839/* A helper function for samepath on windows */
3840static PyObject *
3841posix__getfinalpathname(PyObject *self, PyObject *args)
3842{
3843 HANDLE hFile;
3844 int buf_size;
3845 wchar_t *target_path;
3846 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003847 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003848 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003849
Victor Stinnereb5657a2011-09-30 01:44:27 +02003850 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003851 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003852 path = PyUnicode_AsUnicode(po);
3853 if (path == NULL)
3854 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003855
3856 if(!check_GetFinalPathNameByHandle()) {
3857 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3858 NotImplementedError. */
3859 return PyErr_Format(PyExc_NotImplementedError,
3860 "GetFinalPathNameByHandle not available on this platform");
3861 }
3862
3863 hFile = CreateFileW(
3864 path,
3865 0, /* desired access */
3866 0, /* share mode */
3867 NULL, /* security attributes */
3868 OPEN_EXISTING,
3869 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3870 FILE_FLAG_BACKUP_SEMANTICS,
3871 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003872
Victor Stinnereb5657a2011-09-30 01:44:27 +02003873 if(hFile == INVALID_HANDLE_VALUE)
3874 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003875
3876 /* We have a good handle to the target, use it to determine the
3877 target path name. */
3878 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3879
3880 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003881 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003882
3883 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3884 if(!target_path)
3885 return PyErr_NoMemory();
3886
3887 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3888 buf_size, VOLUME_NAME_DOS);
3889 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003890 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003891
3892 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003893 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003894
3895 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003896 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003897 free(target_path);
3898 return result;
3899
3900} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003901
3902static PyObject *
3903posix__getfileinformation(PyObject *self, PyObject *args)
3904{
3905 HANDLE hFile;
3906 BY_HANDLE_FILE_INFORMATION info;
3907 int fd;
3908
3909 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3910 return NULL;
3911
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003912 if (!_PyVerify_fd(fd))
3913 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003914
3915 hFile = (HANDLE)_get_osfhandle(fd);
3916 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003917 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003918
3919 if (!GetFileInformationByHandle(hFile, &info))
3920 return win32_error("_getfileinformation", NULL);
3921
3922 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3923 info.nFileIndexHigh,
3924 info.nFileIndexLow);
3925}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003926
Brian Curtin95d028f2011-06-09 09:10:38 -05003927PyDoc_STRVAR(posix__isdir__doc__,
3928"Return true if the pathname refers to an existing directory.");
3929
Brian Curtin9c669cc2011-06-08 18:17:18 -05003930static PyObject *
3931posix__isdir(PyObject *self, PyObject *args)
3932{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003933 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003934 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003935 DWORD attributes;
3936
3937 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003938 wchar_t *wpath = PyUnicode_AsUnicode(po);
3939 if (wpath == NULL)
3940 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003941
3942 attributes = GetFileAttributesW(wpath);
3943 if (attributes == INVALID_FILE_ATTRIBUTES)
3944 Py_RETURN_FALSE;
3945 goto check;
3946 }
3947 /* Drop the argument parsing error as narrow strings
3948 are also valid. */
3949 PyErr_Clear();
3950
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003951 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003952 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003953 if (win32_warn_bytes_api())
3954 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003955 attributes = GetFileAttributesA(path);
3956 if (attributes == INVALID_FILE_ATTRIBUTES)
3957 Py_RETURN_FALSE;
3958
3959check:
3960 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3961 Py_RETURN_TRUE;
3962 else
3963 Py_RETURN_FALSE;
3964}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003965#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003967PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003968"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3969Create a directory.\n\
3970\n\
3971If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3972 and path should be relative; path will then be relative to that directory.\n\
3973dir_fd may not be implemented on your platform.\n\
3974 If it is unavailable, using it will raise a NotImplementedError.\n\
3975\n\
3976The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003977
Barry Warsaw53699e91996-12-10 23:23:01 +00003978static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003980{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003981 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003982 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003983 int dir_fd = DEFAULT_DIR_FD;
3984 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3985 PyObject *return_value = NULL;
3986 int result;
3987
3988 memset(&path, 0, sizeof(path));
3989 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
3990 path_converter, &path, &mode,
3991#ifdef HAVE_MKDIRAT
3992 dir_fd_converter, &dir_fd
3993#else
3994 dir_fd_unavailable, &dir_fd
3995#endif
3996 ))
3997 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003998
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003999#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004000 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004001 if (path.wide)
4002 result = CreateDirectoryW(path.wide, NULL);
4003 else
4004 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004006
Larry Hastings9cf065c2012-06-22 16:30:09 -07004007 if (!result) {
4008 return_value = win32_error_object("mkdir", path.object);
4009 goto exit;
4010 }
4011#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013#if HAVE_MKDIRAT
4014 if (dir_fd != DEFAULT_DIR_FD)
4015 result = mkdirat(dir_fd, path.narrow, mode);
4016 else
4017#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004018#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004019 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004020#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004021 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004022#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004023 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004024 if (result < 0) {
4025 return_value = path_error("mkdir", &path);
4026 goto exit;
4027 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004028#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004029 return_value = Py_None;
4030 Py_INCREF(Py_None);
4031exit:
4032 path_cleanup(&path);
4033 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004034}
4035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004036
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004037/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4038#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004039#include <sys/resource.h>
4040#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004041
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004042
4043#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004044PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004045"nice(inc) -> new_priority\n\n\
4046Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004047
Barry Warsaw53699e91996-12-10 23:23:01 +00004048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004049posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004050{
Victor Stinner8c62be82010-05-06 00:08:46 +00004051 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004052
Victor Stinner8c62be82010-05-06 00:08:46 +00004053 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4054 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004055
Victor Stinner8c62be82010-05-06 00:08:46 +00004056 /* There are two flavours of 'nice': one that returns the new
4057 priority (as required by almost all standards out there) and the
4058 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4059 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004060
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 If we are of the nice family that returns the new priority, we
4062 need to clear errno before the call, and check if errno is filled
4063 before calling posix_error() on a returnvalue of -1, because the
4064 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004065
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 errno = 0;
4067 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004068#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004069 if (value == 0)
4070 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004071#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004072 if (value == -1 && errno != 0)
4073 /* either nice() or getpriority() returned an error */
4074 return posix_error();
4075 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004076}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004077#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004078
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004079
4080#ifdef HAVE_GETPRIORITY
4081PyDoc_STRVAR(posix_getpriority__doc__,
4082"getpriority(which, who) -> current_priority\n\n\
4083Get program scheduling priority.");
4084
4085static PyObject *
4086posix_getpriority(PyObject *self, PyObject *args)
4087{
4088 int which, who, retval;
4089
4090 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4091 return NULL;
4092 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004093 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004094 if (errno != 0)
4095 return posix_error();
4096 return PyLong_FromLong((long)retval);
4097}
4098#endif /* HAVE_GETPRIORITY */
4099
4100
4101#ifdef HAVE_SETPRIORITY
4102PyDoc_STRVAR(posix_setpriority__doc__,
4103"setpriority(which, who, prio) -> None\n\n\
4104Set program scheduling priority.");
4105
4106static PyObject *
4107posix_setpriority(PyObject *self, PyObject *args)
4108{
4109 int which, who, prio, retval;
4110
4111 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4112 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004113 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004114 if (retval == -1)
4115 return posix_error();
4116 Py_RETURN_NONE;
4117}
4118#endif /* HAVE_SETPRIORITY */
4119
4120
Barry Warsaw53699e91996-12-10 23:23:01 +00004121static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004123{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124 char *function_name = is_replace ? "replace" : "rename";
4125 path_t src;
4126 path_t dst;
4127 int src_dir_fd = DEFAULT_DIR_FD;
4128 int dst_dir_fd = DEFAULT_DIR_FD;
4129 int dir_fd_specified;
4130 PyObject *return_value = NULL;
4131 char format[24];
4132 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4133
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004134#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004135 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004136 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004137#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004138 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004139#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004140
4141 memset(&src, 0, sizeof(src));
4142 memset(&dst, 0, sizeof(dst));
4143 strcpy(format, "O&O&|$O&O&:");
4144 strcat(format, function_name);
4145 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4146 path_converter, &src,
4147 path_converter, &dst,
4148 dir_fd_converter, &src_dir_fd,
4149 dir_fd_converter, &dst_dir_fd))
4150 return NULL;
4151
4152 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4153 (dst_dir_fd != DEFAULT_DIR_FD);
4154#ifndef HAVE_RENAMEAT
4155 if (dir_fd_specified) {
4156 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4157 goto exit;
4158 }
4159#endif
4160
4161 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4162 PyErr_Format(PyExc_ValueError,
4163 "%s: src and dst must be the same type", function_name);
4164 goto exit;
4165 }
4166
4167#ifdef MS_WINDOWS
4168 Py_BEGIN_ALLOW_THREADS
4169 if (src.wide)
4170 result = MoveFileExW(src.wide, dst.wide, flags);
4171 else
4172 result = MoveFileExA(src.narrow, dst.narrow, flags);
4173 Py_END_ALLOW_THREADS
4174
4175 if (!result) {
4176 return_value = win32_error_object(function_name, dst.object);
4177 goto exit;
4178 }
4179
4180#else
4181 Py_BEGIN_ALLOW_THREADS
4182#ifdef HAVE_RENAMEAT
4183 if (dir_fd_specified)
4184 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4185 else
4186#endif
4187 result = rename(src.narrow, dst.narrow);
4188 Py_END_ALLOW_THREADS
4189
4190 if (result) {
4191 return_value = path_error(function_name, &dst);
4192 goto exit;
4193 }
4194#endif
4195
4196 Py_INCREF(Py_None);
4197 return_value = Py_None;
4198exit:
4199 path_cleanup(&src);
4200 path_cleanup(&dst);
4201 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004202}
4203
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004204PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004205"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4206Rename a file or directory.\n\
4207\n\
4208If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4209 descriptor open to a directory, and the respective path string (src or dst)\n\
4210 should be relative; the path will then be relative to that directory.\n\
4211src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4212 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004213
4214static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004215posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004216{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004217 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004218}
4219
4220PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004221"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4222Rename a file or directory, overwriting the destination.\n\
4223\n\
4224If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4225 descriptor open to a directory, and the respective path string (src or dst)\n\
4226 should be relative; the path will then be relative to that directory.\n\
4227src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4228 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004229
4230static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004231posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004232{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004233 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004234}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004235
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004236PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004237"rmdir(path, *, dir_fd=None)\n\n\
4238Remove a directory.\n\
4239\n\
4240If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4241 and path should be relative; path will then be relative to that directory.\n\
4242dir_fd may not be implemented on your platform.\n\
4243 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004244
Barry Warsaw53699e91996-12-10 23:23:01 +00004245static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004246posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004247{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004248 path_t path;
4249 int dir_fd = DEFAULT_DIR_FD;
4250 static char *keywords[] = {"path", "dir_fd", NULL};
4251 int result;
4252 PyObject *return_value = NULL;
4253
4254 memset(&path, 0, sizeof(path));
4255 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4256 path_converter, &path,
4257#ifdef HAVE_UNLINKAT
4258 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004259#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004260 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004261#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004262 ))
4263 return NULL;
4264
4265 Py_BEGIN_ALLOW_THREADS
4266#ifdef MS_WINDOWS
4267 if (path.wide)
4268 result = RemoveDirectoryW(path.wide);
4269 else
4270 result = RemoveDirectoryA(path.narrow);
4271 result = !result; /* Windows, success=1, UNIX, success=0 */
4272#else
4273#ifdef HAVE_UNLINKAT
4274 if (dir_fd != DEFAULT_DIR_FD)
4275 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4276 else
4277#endif
4278 result = rmdir(path.narrow);
4279#endif
4280 Py_END_ALLOW_THREADS
4281
4282 if (result) {
4283 return_value = path_error("rmdir", &path);
4284 goto exit;
4285 }
4286
4287 return_value = Py_None;
4288 Py_INCREF(Py_None);
4289
4290exit:
4291 path_cleanup(&path);
4292 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004293}
4294
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004295
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004296#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004297PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004298"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004299Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004300
Barry Warsaw53699e91996-12-10 23:23:01 +00004301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004302posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004303{
Victor Stinner8c62be82010-05-06 00:08:46 +00004304 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004305#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004306 wchar_t *command;
4307 if (!PyArg_ParseTuple(args, "u:system", &command))
4308 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004309
Victor Stinner8c62be82010-05-06 00:08:46 +00004310 Py_BEGIN_ALLOW_THREADS
4311 sts = _wsystem(command);
4312 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004313#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004314 PyObject *command_obj;
4315 char *command;
4316 if (!PyArg_ParseTuple(args, "O&:system",
4317 PyUnicode_FSConverter, &command_obj))
4318 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004319
Victor Stinner8c62be82010-05-06 00:08:46 +00004320 command = PyBytes_AsString(command_obj);
4321 Py_BEGIN_ALLOW_THREADS
4322 sts = system(command);
4323 Py_END_ALLOW_THREADS
4324 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004325#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004326 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004327}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004328#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004329
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004330
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004331PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004332"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004333Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004334
Barry Warsaw53699e91996-12-10 23:23:01 +00004335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004336posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004337{
Victor Stinner8c62be82010-05-06 00:08:46 +00004338 int i;
4339 if (!PyArg_ParseTuple(args, "i:umask", &i))
4340 return NULL;
4341 i = (int)umask(i);
4342 if (i < 0)
4343 return posix_error();
4344 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004345}
4346
Brian Curtind40e6f72010-07-08 21:39:08 +00004347#ifdef MS_WINDOWS
4348
4349/* override the default DeleteFileW behavior so that directory
4350symlinks can be removed with this function, the same as with
4351Unix symlinks */
4352BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4353{
4354 WIN32_FILE_ATTRIBUTE_DATA info;
4355 WIN32_FIND_DATAW find_data;
4356 HANDLE find_data_handle;
4357 int is_directory = 0;
4358 int is_link = 0;
4359
4360 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4361 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004362
Brian Curtind40e6f72010-07-08 21:39:08 +00004363 /* Get WIN32_FIND_DATA structure for the path to determine if
4364 it is a symlink */
4365 if(is_directory &&
4366 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4367 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4368
4369 if(find_data_handle != INVALID_HANDLE_VALUE) {
4370 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4371 FindClose(find_data_handle);
4372 }
4373 }
4374 }
4375
4376 if (is_directory && is_link)
4377 return RemoveDirectoryW(lpFileName);
4378
4379 return DeleteFileW(lpFileName);
4380}
4381#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004383PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004384"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004385Remove a file (same as remove()).\n\
4386\n\
4387If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4388 and path should be relative; path will then be relative to that directory.\n\
4389dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004390 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004391
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004392PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004393"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394Remove a file (same as unlink()).\n\
4395\n\
4396If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4397 and path should be relative; path will then be relative to that directory.\n\
4398dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004399 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004400
Barry Warsaw53699e91996-12-10 23:23:01 +00004401static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004402posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004403{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004404 path_t path;
4405 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004406 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004407 int result;
4408 PyObject *return_value = NULL;
4409
4410 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004411 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004412 path_converter, &path,
4413#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004414 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004415#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004416 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004417#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004418 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004419 return NULL;
4420
4421 Py_BEGIN_ALLOW_THREADS
4422#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004423 if (path.wide)
4424 result = Py_DeleteFileW(path.wide);
4425 else
4426 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004427 result = !result; /* Windows, success=1, UNIX, success=0 */
4428#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004429#ifdef HAVE_UNLINKAT
4430 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004431 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432 else
4433#endif /* HAVE_UNLINKAT */
4434 result = unlink(path.narrow);
4435#endif
4436 Py_END_ALLOW_THREADS
4437
4438 if (result) {
4439 return_value = path_error("unlink", &path);
4440 goto exit;
4441 }
4442
4443 return_value = Py_None;
4444 Py_INCREF(Py_None);
4445
4446exit:
4447 path_cleanup(&path);
4448 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004449}
4450
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004451
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004452PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004453"uname() -> uname_result\n\n\
4454Return an object identifying the current operating system.\n\
4455The object behaves like a named tuple with the following fields:\n\
4456 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004457
Larry Hastings605a62d2012-06-24 04:33:36 -07004458static PyStructSequence_Field uname_result_fields[] = {
4459 {"sysname", "operating system name"},
4460 {"nodename", "name of machine on network (implementation-defined)"},
4461 {"release", "operating system release"},
4462 {"version", "operating system version"},
4463 {"machine", "hardware identifier"},
4464 {NULL}
4465};
4466
4467PyDoc_STRVAR(uname_result__doc__,
4468"uname_result: Result from os.uname().\n\n\
4469This object may be accessed either as a tuple of\n\
4470 (sysname, nodename, release, version, machine),\n\
4471or via the attributes sysname, nodename, release, version, and machine.\n\
4472\n\
4473See os.uname for more information.");
4474
4475static PyStructSequence_Desc uname_result_desc = {
4476 "uname_result", /* name */
4477 uname_result__doc__, /* doc */
4478 uname_result_fields,
4479 5
4480};
4481
4482static PyTypeObject UnameResultType;
4483
4484
4485#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004486static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004487posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004488{
Victor Stinner8c62be82010-05-06 00:08:46 +00004489 struct utsname u;
4490 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004491 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004492
Victor Stinner8c62be82010-05-06 00:08:46 +00004493 Py_BEGIN_ALLOW_THREADS
4494 res = uname(&u);
4495 Py_END_ALLOW_THREADS
4496 if (res < 0)
4497 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004498
4499 value = PyStructSequence_New(&UnameResultType);
4500 if (value == NULL)
4501 return NULL;
4502
4503#define SET(i, field) \
4504 { \
4505 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4506 if (!o) { \
4507 Py_DECREF(value); \
4508 return NULL; \
4509 } \
4510 PyStructSequence_SET_ITEM(value, i, o); \
4511 } \
4512
4513 SET(0, u.sysname);
4514 SET(1, u.nodename);
4515 SET(2, u.release);
4516 SET(3, u.version);
4517 SET(4, u.machine);
4518
4519#undef SET
4520
4521 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004522}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004523#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004524
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004525
Larry Hastings9cf065c2012-06-22 16:30:09 -07004526PyDoc_STRVAR(posix_utime__doc__,
4527"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4528Set the access and modified time of path.\n\
4529\n\
4530path may always be specified as a string.\n\
4531On some platforms, path may also be specified as an open file descriptor.\n\
4532 If this functionality is unavailable, using it raises an exception.\n\
4533\n\
4534If times is not None, it must be a tuple (atime, mtime);\n\
4535 atime and mtime should be expressed as float seconds since the epoch.\n\
4536If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4537 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4538 since the epoch.\n\
4539If both times and ns are None, utime uses the current time.\n\
4540Specifying tuples for both times and ns is an error.\n\
4541\n\
4542If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4543 and path should be relative; path will then be relative to that directory.\n\
4544If follow_symlinks is False, and the last element of the path is a symbolic\n\
4545 link, utime will modify the symbolic link itself instead of the file the\n\
4546 link points to.\n\
4547It is an error to use dir_fd or follow_symlinks when specifying path\n\
4548 as an open file descriptor.\n\
4549dir_fd and follow_symlinks may not be available on your platform.\n\
4550 If they are unavailable, using them will raise a NotImplementedError.");
4551
4552typedef struct {
4553 int now;
4554 time_t atime_s;
4555 long atime_ns;
4556 time_t mtime_s;
4557 long mtime_ns;
4558} utime_t;
4559
4560/*
4561 * these macros assume that "utime" is a pointer to a utime_t
4562 * they also intentionally leak the declaration of a pointer named "time"
4563 */
4564#define UTIME_TO_TIMESPEC \
4565 struct timespec ts[2]; \
4566 struct timespec *time; \
4567 if (utime->now) \
4568 time = NULL; \
4569 else { \
4570 ts[0].tv_sec = utime->atime_s; \
4571 ts[0].tv_nsec = utime->atime_ns; \
4572 ts[1].tv_sec = utime->mtime_s; \
4573 ts[1].tv_nsec = utime->mtime_ns; \
4574 time = ts; \
4575 } \
4576
4577#define UTIME_TO_TIMEVAL \
4578 struct timeval tv[2]; \
4579 struct timeval *time; \
4580 if (utime->now) \
4581 time = NULL; \
4582 else { \
4583 tv[0].tv_sec = utime->atime_s; \
4584 tv[0].tv_usec = utime->atime_ns / 1000; \
4585 tv[1].tv_sec = utime->mtime_s; \
4586 tv[1].tv_usec = utime->mtime_ns / 1000; \
4587 time = tv; \
4588 } \
4589
4590#define UTIME_TO_UTIMBUF \
4591 struct utimbuf u[2]; \
4592 struct utimbuf *time; \
4593 if (utime->now) \
4594 time = NULL; \
4595 else { \
4596 u.actime = utime->atime_s; \
4597 u.modtime = utime->mtime_s; \
4598 time = u; \
4599 }
4600
4601#define UTIME_TO_TIME_T \
4602 time_t timet[2]; \
4603 struct timet time; \
4604 if (utime->now) \
4605 time = NULL; \
4606 else { \
4607 timet[0] = utime->atime_s; \
4608 timet[1] = utime->mtime_s; \
4609 time = &timet; \
4610 } \
4611
4612
4613#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4614
4615#if UTIME_HAVE_DIR_FD
4616
4617static int
4618utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4619{
4620#ifdef HAVE_UTIMENSAT
4621 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4622 UTIME_TO_TIMESPEC;
4623 return utimensat(dir_fd, path, time, flags);
4624#elif defined(HAVE_FUTIMESAT)
4625 UTIME_TO_TIMEVAL;
4626 /*
4627 * follow_symlinks will never be false here;
4628 * we only allow !follow_symlinks and dir_fd together
4629 * if we have utimensat()
4630 */
4631 assert(follow_symlinks);
4632 return futimesat(dir_fd, path, time);
4633#endif
4634}
4635
4636#endif
4637
4638#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4639
4640#if UTIME_HAVE_FD
4641
4642static int
4643utime_fd(utime_t *utime, int fd)
4644{
4645#ifdef HAVE_FUTIMENS
4646 UTIME_TO_TIMESPEC;
4647 return futimens(fd, time);
4648#else
4649 UTIME_TO_TIMEVAL;
4650 return futimes(fd, time);
4651#endif
4652}
4653
4654#endif
4655
4656
4657#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4658 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4659
4660#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4661
4662static int
4663utime_nofollow_symlinks(utime_t *utime, char *path)
4664{
4665#ifdef HAVE_UTIMENSAT
4666 UTIME_TO_TIMESPEC;
4667 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4668#else
4669 UTIME_TO_TIMEVAL;
4670 return lutimes(path, time);
4671#endif
4672}
4673
4674#endif
4675
4676#ifndef MS_WINDOWS
4677
4678static int
4679utime_default(utime_t *utime, char *path)
4680{
4681#ifdef HAVE_UTIMENSAT
4682 UTIME_TO_TIMESPEC;
4683 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4684#elif defined(HAVE_UTIMES)
4685 UTIME_TO_TIMEVAL;
4686 return utimes(path, time);
4687#elif defined(HAVE_UTIME_H)
4688 UTIME_TO_UTIMBUF;
4689 return utime(path, time);
4690#else
4691 UTIME_TO_TIME_T;
4692 return utime(path, time);
4693#endif
4694}
4695
4696#endif
4697
Larry Hastings76ad59b2012-05-03 00:30:07 -07004698static int
4699split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4700{
4701 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004702 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004703 divmod = PyNumber_Divmod(py_long, billion);
4704 if (!divmod)
4705 goto exit;
4706 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4707 if ((*s == -1) && PyErr_Occurred())
4708 goto exit;
4709 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004710 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004711 goto exit;
4712
4713 result = 1;
4714exit:
4715 Py_XDECREF(divmod);
4716 return result;
4717}
4718
Larry Hastings9cf065c2012-06-22 16:30:09 -07004719static PyObject *
4720posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004721{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004723 PyObject *times = NULL;
4724 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 int dir_fd = DEFAULT_DIR_FD;
4726 int follow_symlinks = 1;
4727 char *keywords[] = {"path", "times", "ns", "dir_fd",
4728 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004729
Larry Hastings9cf065c2012-06-22 16:30:09 -07004730 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004731
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732#ifdef MS_WINDOWS
4733 HANDLE hFile;
4734 FILETIME atime, mtime;
4735#else
4736 int result;
4737#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004738
Larry Hastings9cf065c2012-06-22 16:30:09 -07004739 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004740
Larry Hastings9cf065c2012-06-22 16:30:09 -07004741 memset(&path, 0, sizeof(path));
4742#if UTIME_HAVE_FD
4743 path.allow_fd = 1;
4744#endif
4745 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4746 "O&|O$OO&p:utime", keywords,
4747 path_converter, &path,
4748 &times, &ns,
4749#if UTIME_HAVE_DIR_FD
4750 dir_fd_converter, &dir_fd,
4751#else
4752 dir_fd_unavailable, &dir_fd,
4753#endif
4754 &follow_symlinks
4755 ))
4756 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004757
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 if (times && (times != Py_None) && ns) {
4759 PyErr_SetString(PyExc_ValueError,
4760 "utime: you may specify either 'times'"
4761 " or 'ns' but not both");
4762 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004763 }
4764
4765 if (times && (times != Py_None)) {
4766 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767 PyErr_SetString(PyExc_TypeError,
4768 "utime: 'times' must be either"
4769 " a tuple of two ints or None");
4770 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004771 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004773 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004774 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004775 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776 &utime.mtime_s, &utime.mtime_ns) == -1) {
4777 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004778 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004779 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004781 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 PyErr_SetString(PyExc_TypeError,
4783 "utime: 'ns' must be a tuple of two ints");
4784 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004785 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004786 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004787 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004789 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790 &utime.mtime_s, &utime.mtime_ns)) {
4791 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004792 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004793 }
4794 else {
4795 /* times and ns are both None/unspecified. use "now". */
4796 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004797 }
4798
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4800 if (follow_symlinks_specified("utime", follow_symlinks))
4801 goto exit;
4802#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004803
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4805 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4806 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4807 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004808
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809#if !defined(HAVE_UTIMENSAT)
4810 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004811 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812 "utime: cannot use dir_fd and follow_symlinks "
4813 "together on this platform");
4814 goto exit;
4815 }
4816#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004817
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004818#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004819 Py_BEGIN_ALLOW_THREADS
4820 if (path.wide)
4821 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004822 NULL, OPEN_EXISTING,
4823 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004824 else
4825 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004826 NULL, OPEN_EXISTING,
4827 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828 Py_END_ALLOW_THREADS
4829 if (hFile == INVALID_HANDLE_VALUE) {
4830 win32_error_object("utime", path.object);
4831 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004832 }
4833
Larry Hastings9cf065c2012-06-22 16:30:09 -07004834 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 SYSTEMTIME now;
4836 GetSystemTime(&now);
4837 if (!SystemTimeToFileTime(&now, &mtime) ||
4838 !SystemTimeToFileTime(&now, &atime)) {
4839 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004841 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4845 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 }
4847 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4848 /* Avoid putting the file name into the error here,
4849 as that may confuse the user into believing that
4850 something is wrong with the file, when it also
4851 could be the time stamp that gives a problem. */
4852 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004853 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004854 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004855#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004856 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004857
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4859 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4860 result = utime_nofollow_symlinks(&utime, path.narrow);
4861 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004862#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004863
4864#if UTIME_HAVE_DIR_FD
4865 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4866 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4867 else
4868#endif
4869
4870#if UTIME_HAVE_FD
4871 if (path.fd != -1)
4872 result = utime_fd(&utime, path.fd);
4873 else
4874#endif
4875
4876 result = utime_default(&utime, path.narrow);
4877
4878 Py_END_ALLOW_THREADS
4879
4880 if (result < 0) {
4881 /* see previous comment about not putting filename in error here */
4882 return_value = posix_error();
4883 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004885
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004886#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004887
4888 Py_INCREF(Py_None);
4889 return_value = Py_None;
4890
4891exit:
4892 path_cleanup(&path);
4893#ifdef MS_WINDOWS
4894 if (hFile != INVALID_HANDLE_VALUE)
4895 CloseHandle(hFile);
4896#endif
4897 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004898}
4899
Guido van Rossum3b066191991-06-04 19:40:25 +00004900/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004901
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004902PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004903"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004904Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004905
Barry Warsaw53699e91996-12-10 23:23:01 +00004906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004907posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004908{
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 int sts;
4910 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4911 return NULL;
4912 _exit(sts);
4913 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004914}
4915
Martin v. Löwis114619e2002-10-07 06:44:21 +00004916#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4917static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004918free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004919{
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 Py_ssize_t i;
4921 for (i = 0; i < count; i++)
4922 PyMem_Free(array[i]);
4923 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004924}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004925
Antoine Pitrou69f71142009-05-24 21:25:49 +00004926static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004927int fsconvert_strdup(PyObject *o, char**out)
4928{
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 PyObject *bytes;
4930 Py_ssize_t size;
4931 if (!PyUnicode_FSConverter(o, &bytes))
4932 return 0;
4933 size = PyBytes_GET_SIZE(bytes);
4934 *out = PyMem_Malloc(size+1);
4935 if (!*out)
4936 return 0;
4937 memcpy(*out, PyBytes_AsString(bytes), size+1);
4938 Py_DECREF(bytes);
4939 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004940}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004941#endif
4942
Ross Lagerwall7807c352011-03-17 20:20:30 +02004943#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004944static char**
4945parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4946{
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 char **envlist;
4948 Py_ssize_t i, pos, envc;
4949 PyObject *keys=NULL, *vals=NULL;
4950 PyObject *key, *val, *key2, *val2;
4951 char *p, *k, *v;
4952 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004953
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 i = PyMapping_Size(env);
4955 if (i < 0)
4956 return NULL;
4957 envlist = PyMem_NEW(char *, i + 1);
4958 if (envlist == NULL) {
4959 PyErr_NoMemory();
4960 return NULL;
4961 }
4962 envc = 0;
4963 keys = PyMapping_Keys(env);
4964 vals = PyMapping_Values(env);
4965 if (!keys || !vals)
4966 goto error;
4967 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4968 PyErr_Format(PyExc_TypeError,
4969 "env.keys() or env.values() is not a list");
4970 goto error;
4971 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004972
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 for (pos = 0; pos < i; pos++) {
4974 key = PyList_GetItem(keys, pos);
4975 val = PyList_GetItem(vals, pos);
4976 if (!key || !val)
4977 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004978
Victor Stinner8c62be82010-05-06 00:08:46 +00004979 if (PyUnicode_FSConverter(key, &key2) == 0)
4980 goto error;
4981 if (PyUnicode_FSConverter(val, &val2) == 0) {
4982 Py_DECREF(key2);
4983 goto error;
4984 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004985
4986#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4988 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004989#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 k = PyBytes_AsString(key2);
4991 v = PyBytes_AsString(val2);
4992 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004993
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 p = PyMem_NEW(char, len);
4995 if (p == NULL) {
4996 PyErr_NoMemory();
4997 Py_DECREF(key2);
4998 Py_DECREF(val2);
4999 goto error;
5000 }
5001 PyOS_snprintf(p, len, "%s=%s", k, v);
5002 envlist[envc++] = p;
5003 Py_DECREF(key2);
5004 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005005#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00005006 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005007#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005008 }
5009 Py_DECREF(vals);
5010 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005011
Victor Stinner8c62be82010-05-06 00:08:46 +00005012 envlist[envc] = 0;
5013 *envc_ptr = envc;
5014 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005015
5016error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 Py_XDECREF(keys);
5018 Py_XDECREF(vals);
5019 while (--envc >= 0)
5020 PyMem_DEL(envlist[envc]);
5021 PyMem_DEL(envlist);
5022 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005023}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005024
Ross Lagerwall7807c352011-03-17 20:20:30 +02005025static char**
5026parse_arglist(PyObject* argv, Py_ssize_t *argc)
5027{
5028 int i;
5029 char **argvlist = PyMem_NEW(char *, *argc+1);
5030 if (argvlist == NULL) {
5031 PyErr_NoMemory();
5032 return NULL;
5033 }
5034 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005035 PyObject* item = PySequence_ITEM(argv, i);
5036 if (item == NULL)
5037 goto fail;
5038 if (!fsconvert_strdup(item, &argvlist[i])) {
5039 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005040 goto fail;
5041 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005042 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043 }
5044 argvlist[*argc] = NULL;
5045 return argvlist;
5046fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005047 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005048 free_string_array(argvlist, *argc);
5049 return NULL;
5050}
5051#endif
5052
5053#ifdef HAVE_EXECV
5054PyDoc_STRVAR(posix_execv__doc__,
5055"execv(path, args)\n\n\
5056Execute an executable path with arguments, replacing current process.\n\
5057\n\
5058 path: path of executable file\n\
5059 args: tuple or list of strings");
5060
5061static PyObject *
5062posix_execv(PyObject *self, PyObject *args)
5063{
5064 PyObject *opath;
5065 char *path;
5066 PyObject *argv;
5067 char **argvlist;
5068 Py_ssize_t argc;
5069
5070 /* execv has two arguments: (path, argv), where
5071 argv is a list or tuple of strings. */
5072
5073 if (!PyArg_ParseTuple(args, "O&O:execv",
5074 PyUnicode_FSConverter,
5075 &opath, &argv))
5076 return NULL;
5077 path = PyBytes_AsString(opath);
5078 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5079 PyErr_SetString(PyExc_TypeError,
5080 "execv() arg 2 must be a tuple or list");
5081 Py_DECREF(opath);
5082 return NULL;
5083 }
5084 argc = PySequence_Size(argv);
5085 if (argc < 1) {
5086 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5087 Py_DECREF(opath);
5088 return NULL;
5089 }
5090
5091 argvlist = parse_arglist(argv, &argc);
5092 if (argvlist == NULL) {
5093 Py_DECREF(opath);
5094 return NULL;
5095 }
5096
5097 execv(path, argvlist);
5098
5099 /* If we get here it's definitely an error */
5100
5101 free_string_array(argvlist, argc);
5102 Py_DECREF(opath);
5103 return posix_error();
5104}
5105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005106PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005107"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005108Execute a path with arguments and environment, replacing current process.\n\
5109\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 path: path of executable file\n\
5111 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005112 env: dictionary of strings mapping to strings\n\
5113\n\
5114On some platforms, you may specify an open file descriptor for path;\n\
5115 execve will execute the program the file descriptor is open to.\n\
5116 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005117
Barry Warsaw53699e91996-12-10 23:23:01 +00005118static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005119posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005120{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005121 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005123 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005124 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005125 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005126 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005127
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 /* execve has three arguments: (path, argv, env), where
5129 argv is a list or tuple of strings and env is a dictionary
5130 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005131
Larry Hastings9cf065c2012-06-22 16:30:09 -07005132 memset(&path, 0, sizeof(path));
5133#ifdef HAVE_FEXECVE
5134 path.allow_fd = 1;
5135#endif
5136 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5137 path_converter, &path,
5138 &argv, &env
5139 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005141
Ross Lagerwall7807c352011-03-17 20:20:30 +02005142 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005144 "execve: argv must be a tuple or list");
5145 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005147 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 if (!PyMapping_Check(env)) {
5149 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005150 "execve: environment must be a mapping object");
5151 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005153
Ross Lagerwall7807c352011-03-17 20:20:30 +02005154 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005157 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005158
Victor Stinner8c62be82010-05-06 00:08:46 +00005159 envlist = parse_envlist(env, &envc);
5160 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005161 goto fail;
5162
Larry Hastings9cf065c2012-06-22 16:30:09 -07005163#ifdef HAVE_FEXECVE
5164 if (path.fd > -1)
5165 fexecve(path.fd, argvlist, envlist);
5166 else
5167#endif
5168 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005169
5170 /* If we get here it's definitely an error */
5171
Larry Hastings9cf065c2012-06-22 16:30:09 -07005172 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005173
5174 while (--envc >= 0)
5175 PyMem_DEL(envlist[envc]);
5176 PyMem_DEL(envlist);
5177 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005178 if (argvlist)
5179 free_string_array(argvlist, argc);
5180 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005181 return NULL;
5182}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005183#endif /* HAVE_EXECV */
5184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005185
Guido van Rossuma1065681999-01-25 23:20:23 +00005186#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005187PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005188"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005189Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005190\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005191 mode: mode of process creation\n\
5192 path: path of executable file\n\
5193 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005194
5195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005196posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005197{
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 PyObject *opath;
5199 char *path;
5200 PyObject *argv;
5201 char **argvlist;
5202 int mode, i;
5203 Py_ssize_t argc;
5204 Py_intptr_t spawnval;
5205 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005206
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 /* spawnv has three arguments: (mode, path, argv), where
5208 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005209
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5211 PyUnicode_FSConverter,
5212 &opath, &argv))
5213 return NULL;
5214 path = PyBytes_AsString(opath);
5215 if (PyList_Check(argv)) {
5216 argc = PyList_Size(argv);
5217 getitem = PyList_GetItem;
5218 }
5219 else if (PyTuple_Check(argv)) {
5220 argc = PyTuple_Size(argv);
5221 getitem = PyTuple_GetItem;
5222 }
5223 else {
5224 PyErr_SetString(PyExc_TypeError,
5225 "spawnv() arg 2 must be a tuple or list");
5226 Py_DECREF(opath);
5227 return NULL;
5228 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005229
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 argvlist = PyMem_NEW(char *, argc+1);
5231 if (argvlist == NULL) {
5232 Py_DECREF(opath);
5233 return PyErr_NoMemory();
5234 }
5235 for (i = 0; i < argc; i++) {
5236 if (!fsconvert_strdup((*getitem)(argv, i),
5237 &argvlist[i])) {
5238 free_string_array(argvlist, i);
5239 PyErr_SetString(
5240 PyExc_TypeError,
5241 "spawnv() arg 2 must contain only strings");
5242 Py_DECREF(opath);
5243 return NULL;
5244 }
5245 }
5246 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005247
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005248#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005249 Py_BEGIN_ALLOW_THREADS
5250 spawnval = spawnv(mode, path, argvlist);
5251 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005252#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 if (mode == _OLD_P_OVERLAY)
5254 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005255
Victor Stinner8c62be82010-05-06 00:08:46 +00005256 Py_BEGIN_ALLOW_THREADS
5257 spawnval = _spawnv(mode, path, argvlist);
5258 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005259#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005260
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 free_string_array(argvlist, argc);
5262 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005263
Victor Stinner8c62be82010-05-06 00:08:46 +00005264 if (spawnval == -1)
5265 return posix_error();
5266 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005267#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005268 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005269#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005271#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005272}
5273
5274
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005275PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005276"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005277Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005278\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 mode: mode of process creation\n\
5280 path: path of executable file\n\
5281 args: tuple or list of arguments\n\
5282 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005283
5284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005285posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005286{
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 PyObject *opath;
5288 char *path;
5289 PyObject *argv, *env;
5290 char **argvlist;
5291 char **envlist;
5292 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005293 int mode;
5294 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 Py_intptr_t spawnval;
5296 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5297 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005298
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 /* spawnve has four arguments: (mode, path, argv, env), where
5300 argv is a list or tuple of strings and env is a dictionary
5301 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005302
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5304 PyUnicode_FSConverter,
5305 &opath, &argv, &env))
5306 return NULL;
5307 path = PyBytes_AsString(opath);
5308 if (PyList_Check(argv)) {
5309 argc = PyList_Size(argv);
5310 getitem = PyList_GetItem;
5311 }
5312 else if (PyTuple_Check(argv)) {
5313 argc = PyTuple_Size(argv);
5314 getitem = PyTuple_GetItem;
5315 }
5316 else {
5317 PyErr_SetString(PyExc_TypeError,
5318 "spawnve() arg 2 must be a tuple or list");
5319 goto fail_0;
5320 }
5321 if (!PyMapping_Check(env)) {
5322 PyErr_SetString(PyExc_TypeError,
5323 "spawnve() arg 3 must be a mapping object");
5324 goto fail_0;
5325 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005326
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 argvlist = PyMem_NEW(char *, argc+1);
5328 if (argvlist == NULL) {
5329 PyErr_NoMemory();
5330 goto fail_0;
5331 }
5332 for (i = 0; i < argc; i++) {
5333 if (!fsconvert_strdup((*getitem)(argv, i),
5334 &argvlist[i]))
5335 {
5336 lastarg = i;
5337 goto fail_1;
5338 }
5339 }
5340 lastarg = argc;
5341 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005342
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 envlist = parse_envlist(env, &envc);
5344 if (envlist == NULL)
5345 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005346
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005347#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 Py_BEGIN_ALLOW_THREADS
5349 spawnval = spawnve(mode, path, argvlist, envlist);
5350 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005351#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005352 if (mode == _OLD_P_OVERLAY)
5353 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005354
Victor Stinner8c62be82010-05-06 00:08:46 +00005355 Py_BEGIN_ALLOW_THREADS
5356 spawnval = _spawnve(mode, path, argvlist, envlist);
5357 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005358#endif
Tim Peters25059d32001-12-07 20:35:43 +00005359
Victor Stinner8c62be82010-05-06 00:08:46 +00005360 if (spawnval == -1)
5361 (void) posix_error();
5362 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005363#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005364 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005365#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005367#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005368
Victor Stinner8c62be82010-05-06 00:08:46 +00005369 while (--envc >= 0)
5370 PyMem_DEL(envlist[envc]);
5371 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005372 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005373 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005374 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 Py_DECREF(opath);
5376 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005377}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005378
5379/* OS/2 supports spawnvp & spawnvpe natively */
5380#if defined(PYOS_OS2)
5381PyDoc_STRVAR(posix_spawnvp__doc__,
5382"spawnvp(mode, file, args)\n\n\
5383Execute the program 'file' in a new process, using the environment\n\
5384search path to find the file.\n\
5385\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005386 mode: mode of process creation\n\
5387 file: executable file name\n\
5388 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005389
5390static PyObject *
5391posix_spawnvp(PyObject *self, PyObject *args)
5392{
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 PyObject *opath;
5394 char *path;
5395 PyObject *argv;
5396 char **argvlist;
5397 int mode, i, argc;
5398 Py_intptr_t spawnval;
5399 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005400
Victor Stinner8c62be82010-05-06 00:08:46 +00005401 /* spawnvp has three arguments: (mode, path, argv), where
5402 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005403
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5405 PyUnicode_FSConverter,
5406 &opath, &argv))
5407 return NULL;
5408 path = PyBytes_AsString(opath);
5409 if (PyList_Check(argv)) {
5410 argc = PyList_Size(argv);
5411 getitem = PyList_GetItem;
5412 }
5413 else if (PyTuple_Check(argv)) {
5414 argc = PyTuple_Size(argv);
5415 getitem = PyTuple_GetItem;
5416 }
5417 else {
5418 PyErr_SetString(PyExc_TypeError,
5419 "spawnvp() arg 2 must be a tuple or list");
5420 Py_DECREF(opath);
5421 return NULL;
5422 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005423
Victor Stinner8c62be82010-05-06 00:08:46 +00005424 argvlist = PyMem_NEW(char *, argc+1);
5425 if (argvlist == NULL) {
5426 Py_DECREF(opath);
5427 return PyErr_NoMemory();
5428 }
5429 for (i = 0; i < argc; i++) {
5430 if (!fsconvert_strdup((*getitem)(argv, i),
5431 &argvlist[i])) {
5432 free_string_array(argvlist, i);
5433 PyErr_SetString(
5434 PyExc_TypeError,
5435 "spawnvp() arg 2 must contain only strings");
5436 Py_DECREF(opath);
5437 return NULL;
5438 }
5439 }
5440 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005441
Victor Stinner8c62be82010-05-06 00:08:46 +00005442 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005443#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005444 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005445#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005446 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005447#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005448 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005449
Victor Stinner8c62be82010-05-06 00:08:46 +00005450 free_string_array(argvlist, argc);
5451 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005452
Victor Stinner8c62be82010-05-06 00:08:46 +00005453 if (spawnval == -1)
5454 return posix_error();
5455 else
5456 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005457}
5458
5459
5460PyDoc_STRVAR(posix_spawnvpe__doc__,
5461"spawnvpe(mode, file, args, env)\n\n\
5462Execute the program 'file' in a new process, using the environment\n\
5463search path to find the file.\n\
5464\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 mode: mode of process creation\n\
5466 file: executable file name\n\
5467 args: tuple or list of arguments\n\
5468 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005469
5470static PyObject *
5471posix_spawnvpe(PyObject *self, PyObject *args)
5472{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005473 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005474 char *path;
5475 PyObject *argv, *env;
5476 char **argvlist;
5477 char **envlist;
5478 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005479 int mode;
5480 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005481 Py_intptr_t spawnval;
5482 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5483 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005484
Victor Stinner8c62be82010-05-06 00:08:46 +00005485 /* spawnvpe has four arguments: (mode, path, argv, env), where
5486 argv is a list or tuple of strings and env is a dictionary
5487 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005488
Victor Stinner8c62be82010-05-06 00:08:46 +00005489 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5490 PyUnicode_FSConverter,
5491 &opath, &argv, &env))
5492 return NULL;
5493 path = PyBytes_AsString(opath);
5494 if (PyList_Check(argv)) {
5495 argc = PyList_Size(argv);
5496 getitem = PyList_GetItem;
5497 }
5498 else if (PyTuple_Check(argv)) {
5499 argc = PyTuple_Size(argv);
5500 getitem = PyTuple_GetItem;
5501 }
5502 else {
5503 PyErr_SetString(PyExc_TypeError,
5504 "spawnvpe() arg 2 must be a tuple or list");
5505 goto fail_0;
5506 }
5507 if (!PyMapping_Check(env)) {
5508 PyErr_SetString(PyExc_TypeError,
5509 "spawnvpe() arg 3 must be a mapping object");
5510 goto fail_0;
5511 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005512
Victor Stinner8c62be82010-05-06 00:08:46 +00005513 argvlist = PyMem_NEW(char *, argc+1);
5514 if (argvlist == NULL) {
5515 PyErr_NoMemory();
5516 goto fail_0;
5517 }
5518 for (i = 0; i < argc; i++) {
5519 if (!fsconvert_strdup((*getitem)(argv, i),
5520 &argvlist[i]))
5521 {
5522 lastarg = i;
5523 goto fail_1;
5524 }
5525 }
5526 lastarg = argc;
5527 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005528
Victor Stinner8c62be82010-05-06 00:08:46 +00005529 envlist = parse_envlist(env, &envc);
5530 if (envlist == NULL)
5531 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005532
Victor Stinner8c62be82010-05-06 00:08:46 +00005533 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005534#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005535 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005536#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005537 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005538#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005539 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005540
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 if (spawnval == -1)
5542 (void) posix_error();
5543 else
5544 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005545
Victor Stinner8c62be82010-05-06 00:08:46 +00005546 while (--envc >= 0)
5547 PyMem_DEL(envlist[envc]);
5548 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005549 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005550 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005551 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005552 Py_DECREF(opath);
5553 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005554}
5555#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005556#endif /* HAVE_SPAWNV */
5557
5558
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005559#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005560PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005561"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005562Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5563\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005564Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005565
5566static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005567posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005568{
Victor Stinner8c62be82010-05-06 00:08:46 +00005569 pid_t pid;
5570 int result = 0;
5571 _PyImport_AcquireLock();
5572 pid = fork1();
5573 if (pid == 0) {
5574 /* child: this clobbers and resets the import lock. */
5575 PyOS_AfterFork();
5576 } else {
5577 /* parent: release the import lock. */
5578 result = _PyImport_ReleaseLock();
5579 }
5580 if (pid == -1)
5581 return posix_error();
5582 if (result < 0) {
5583 /* Don't clobber the OSError if the fork failed. */
5584 PyErr_SetString(PyExc_RuntimeError,
5585 "not holding the import lock");
5586 return NULL;
5587 }
5588 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005589}
5590#endif
5591
5592
Guido van Rossumad0ee831995-03-01 10:34:45 +00005593#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005594PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005595"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005596Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005597Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005598
Barry Warsaw53699e91996-12-10 23:23:01 +00005599static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005600posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005601{
Victor Stinner8c62be82010-05-06 00:08:46 +00005602 pid_t pid;
5603 int result = 0;
5604 _PyImport_AcquireLock();
5605 pid = fork();
5606 if (pid == 0) {
5607 /* child: this clobbers and resets the import lock. */
5608 PyOS_AfterFork();
5609 } else {
5610 /* parent: release the import lock. */
5611 result = _PyImport_ReleaseLock();
5612 }
5613 if (pid == -1)
5614 return posix_error();
5615 if (result < 0) {
5616 /* Don't clobber the OSError if the fork failed. */
5617 PyErr_SetString(PyExc_RuntimeError,
5618 "not holding the import lock");
5619 return NULL;
5620 }
5621 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005622}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005623#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005624
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005625#ifdef HAVE_SCHED_H
5626
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005627#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5628
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005629PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5630"sched_get_priority_max(policy)\n\n\
5631Get the maximum scheduling priority for *policy*.");
5632
5633static PyObject *
5634posix_sched_get_priority_max(PyObject *self, PyObject *args)
5635{
5636 int policy, max;
5637
5638 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5639 return NULL;
5640 max = sched_get_priority_max(policy);
5641 if (max < 0)
5642 return posix_error();
5643 return PyLong_FromLong(max);
5644}
5645
5646PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5647"sched_get_priority_min(policy)\n\n\
5648Get the minimum scheduling priority for *policy*.");
5649
5650static PyObject *
5651posix_sched_get_priority_min(PyObject *self, PyObject *args)
5652{
5653 int policy, min;
5654
5655 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5656 return NULL;
5657 min = sched_get_priority_min(policy);
5658 if (min < 0)
5659 return posix_error();
5660 return PyLong_FromLong(min);
5661}
5662
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005663#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5664
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005665#ifdef HAVE_SCHED_SETSCHEDULER
5666
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005667PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5668"sched_getscheduler(pid)\n\n\
5669Get the scheduling policy for the process with a PID of *pid*.\n\
5670Passing a PID of 0 returns the scheduling policy for the calling process.");
5671
5672static PyObject *
5673posix_sched_getscheduler(PyObject *self, PyObject *args)
5674{
5675 pid_t pid;
5676 int policy;
5677
5678 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5679 return NULL;
5680 policy = sched_getscheduler(pid);
5681 if (policy < 0)
5682 return posix_error();
5683 return PyLong_FromLong(policy);
5684}
5685
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005686#endif
5687
5688#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5689
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005690static PyObject *
5691sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5692{
5693 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005694 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005695
5696 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5697 return NULL;
5698 res = PyStructSequence_New(type);
5699 if (!res)
5700 return NULL;
5701 Py_INCREF(priority);
5702 PyStructSequence_SET_ITEM(res, 0, priority);
5703 return res;
5704}
5705
5706PyDoc_STRVAR(sched_param__doc__,
5707"sched_param(sched_priority): A scheduling parameter.\n\n\
5708Current has only one field: sched_priority");
5709
5710static PyStructSequence_Field sched_param_fields[] = {
5711 {"sched_priority", "the scheduling priority"},
5712 {0}
5713};
5714
5715static PyStructSequence_Desc sched_param_desc = {
5716 "sched_param", /* name */
5717 sched_param__doc__, /* doc */
5718 sched_param_fields,
5719 1
5720};
5721
5722static int
5723convert_sched_param(PyObject *param, struct sched_param *res)
5724{
5725 long priority;
5726
5727 if (Py_TYPE(param) != &SchedParamType) {
5728 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5729 return 0;
5730 }
5731 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5732 if (priority == -1 && PyErr_Occurred())
5733 return 0;
5734 if (priority > INT_MAX || priority < INT_MIN) {
5735 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5736 return 0;
5737 }
5738 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5739 return 1;
5740}
5741
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005742#endif
5743
5744#ifdef HAVE_SCHED_SETSCHEDULER
5745
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005746PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5747"sched_setscheduler(pid, policy, param)\n\n\
5748Set the scheduling policy, *policy*, for *pid*.\n\
5749If *pid* is 0, the calling process is changed.\n\
5750*param* is an instance of sched_param.");
5751
5752static PyObject *
5753posix_sched_setscheduler(PyObject *self, PyObject *args)
5754{
5755 pid_t pid;
5756 int policy;
5757 struct sched_param param;
5758
5759 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5760 &pid, &policy, &convert_sched_param, &param))
5761 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005762
5763 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005764 ** sched_setscheduler() returns 0 in Linux, but the previous
5765 ** scheduling policy under Solaris/Illumos, and others.
5766 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005767 */
5768 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005769 return posix_error();
5770 Py_RETURN_NONE;
5771}
5772
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005773#endif
5774
5775#ifdef HAVE_SCHED_SETPARAM
5776
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005777PyDoc_STRVAR(posix_sched_getparam__doc__,
5778"sched_getparam(pid) -> sched_param\n\n\
5779Returns scheduling parameters for the process with *pid* as an instance of the\n\
5780sched_param class. A PID of 0 means the calling process.");
5781
5782static PyObject *
5783posix_sched_getparam(PyObject *self, PyObject *args)
5784{
5785 pid_t pid;
5786 struct sched_param param;
5787 PyObject *res, *priority;
5788
5789 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5790 return NULL;
5791 if (sched_getparam(pid, &param))
5792 return posix_error();
5793 res = PyStructSequence_New(&SchedParamType);
5794 if (!res)
5795 return NULL;
5796 priority = PyLong_FromLong(param.sched_priority);
5797 if (!priority) {
5798 Py_DECREF(res);
5799 return NULL;
5800 }
5801 PyStructSequence_SET_ITEM(res, 0, priority);
5802 return res;
5803}
5804
5805PyDoc_STRVAR(posix_sched_setparam__doc__,
5806"sched_setparam(pid, param)\n\n\
5807Set scheduling parameters for a process with PID *pid*.\n\
5808A PID of 0 means the calling process.");
5809
5810static PyObject *
5811posix_sched_setparam(PyObject *self, PyObject *args)
5812{
5813 pid_t pid;
5814 struct sched_param param;
5815
5816 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5817 &pid, &convert_sched_param, &param))
5818 return NULL;
5819 if (sched_setparam(pid, &param))
5820 return posix_error();
5821 Py_RETURN_NONE;
5822}
5823
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005824#endif
5825
5826#ifdef HAVE_SCHED_RR_GET_INTERVAL
5827
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005828PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5829"sched_rr_get_interval(pid) -> float\n\n\
5830Return the round-robin quantum for the process with PID *pid* in seconds.");
5831
5832static PyObject *
5833posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5834{
5835 pid_t pid;
5836 struct timespec interval;
5837
5838 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5839 return NULL;
5840 if (sched_rr_get_interval(pid, &interval))
5841 return posix_error();
5842 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5843}
5844
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005845#endif
5846
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005847PyDoc_STRVAR(posix_sched_yield__doc__,
5848"sched_yield()\n\n\
5849Voluntarily relinquish the CPU.");
5850
5851static PyObject *
5852posix_sched_yield(PyObject *self, PyObject *noargs)
5853{
5854 if (sched_yield())
5855 return posix_error();
5856 Py_RETURN_NONE;
5857}
5858
Benjamin Peterson2740af82011-08-02 17:41:34 -05005859#ifdef HAVE_SCHED_SETAFFINITY
5860
Antoine Pitrou84869872012-08-04 16:16:35 +02005861/* The minimum number of CPUs allocated in a cpu_set_t */
5862static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005863
5864PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5865"sched_setaffinity(pid, cpu_set)\n\n\
5866Set the affinity of the process with PID *pid* to *cpu_set*.");
5867
5868static PyObject *
5869posix_sched_setaffinity(PyObject *self, PyObject *args)
5870{
5871 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005872 int ncpus;
5873 size_t setsize;
5874 cpu_set_t *mask = NULL;
5875 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005876
Antoine Pitrou84869872012-08-04 16:16:35 +02005877 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5878 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005879 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005880
5881 iterator = PyObject_GetIter(iterable);
5882 if (iterator == NULL)
5883 return NULL;
5884
5885 ncpus = NCPUS_START;
5886 setsize = CPU_ALLOC_SIZE(ncpus);
5887 mask = CPU_ALLOC(ncpus);
5888 if (mask == NULL) {
5889 PyErr_NoMemory();
5890 goto error;
5891 }
5892 CPU_ZERO_S(setsize, mask);
5893
5894 while ((item = PyIter_Next(iterator))) {
5895 long cpu;
5896 if (!PyLong_Check(item)) {
5897 PyErr_Format(PyExc_TypeError,
5898 "expected an iterator of ints, "
5899 "but iterator yielded %R",
5900 Py_TYPE(item));
5901 Py_DECREF(item);
5902 goto error;
5903 }
5904 cpu = PyLong_AsLong(item);
5905 Py_DECREF(item);
5906 if (cpu < 0) {
5907 if (!PyErr_Occurred())
5908 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5909 goto error;
5910 }
5911 if (cpu > INT_MAX - 1) {
5912 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5913 goto error;
5914 }
5915 if (cpu >= ncpus) {
5916 /* Grow CPU mask to fit the CPU number */
5917 int newncpus = ncpus;
5918 cpu_set_t *newmask;
5919 size_t newsetsize;
5920 while (newncpus <= cpu) {
5921 if (newncpus > INT_MAX / 2)
5922 newncpus = cpu + 1;
5923 else
5924 newncpus = newncpus * 2;
5925 }
5926 newmask = CPU_ALLOC(newncpus);
5927 if (newmask == NULL) {
5928 PyErr_NoMemory();
5929 goto error;
5930 }
5931 newsetsize = CPU_ALLOC_SIZE(newncpus);
5932 CPU_ZERO_S(newsetsize, newmask);
5933 memcpy(newmask, mask, setsize);
5934 CPU_FREE(mask);
5935 setsize = newsetsize;
5936 mask = newmask;
5937 ncpus = newncpus;
5938 }
5939 CPU_SET_S(cpu, setsize, mask);
5940 }
5941 Py_CLEAR(iterator);
5942
5943 if (sched_setaffinity(pid, setsize, mask)) {
5944 posix_error();
5945 goto error;
5946 }
5947 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005948 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005949
5950error:
5951 if (mask)
5952 CPU_FREE(mask);
5953 Py_XDECREF(iterator);
5954 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005955}
5956
5957PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5958"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5959Return the affinity of the process with PID *pid*.\n\
5960The returned cpu_set will be of size *ncpus*.");
5961
5962static PyObject *
5963posix_sched_getaffinity(PyObject *self, PyObject *args)
5964{
5965 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005966 int cpu, ncpus, count;
5967 size_t setsize;
5968 cpu_set_t *mask = NULL;
5969 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005970
Antoine Pitrou84869872012-08-04 16:16:35 +02005971 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5972 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005973 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005974
5975 ncpus = NCPUS_START;
5976 while (1) {
5977 setsize = CPU_ALLOC_SIZE(ncpus);
5978 mask = CPU_ALLOC(ncpus);
5979 if (mask == NULL)
5980 return PyErr_NoMemory();
5981 if (sched_getaffinity(pid, setsize, mask) == 0)
5982 break;
5983 CPU_FREE(mask);
5984 if (errno != EINVAL)
5985 return posix_error();
5986 if (ncpus > INT_MAX / 2) {
5987 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5988 "a large enough CPU set");
5989 return NULL;
5990 }
5991 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005992 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005993
5994 res = PySet_New(NULL);
5995 if (res == NULL)
5996 goto error;
5997 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5998 if (CPU_ISSET_S(cpu, setsize, mask)) {
5999 PyObject *cpu_num = PyLong_FromLong(cpu);
6000 --count;
6001 if (cpu_num == NULL)
6002 goto error;
6003 if (PySet_Add(res, cpu_num)) {
6004 Py_DECREF(cpu_num);
6005 goto error;
6006 }
6007 Py_DECREF(cpu_num);
6008 }
6009 }
6010 CPU_FREE(mask);
6011 return res;
6012
6013error:
6014 if (mask)
6015 CPU_FREE(mask);
6016 Py_XDECREF(res);
6017 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006018}
6019
Benjamin Peterson2740af82011-08-02 17:41:34 -05006020#endif /* HAVE_SCHED_SETAFFINITY */
6021
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006022#endif /* HAVE_SCHED_H */
6023
Neal Norwitzb59798b2003-03-21 01:43:31 +00006024/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006025/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6026#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006027#define DEV_PTY_FILE "/dev/ptc"
6028#define HAVE_DEV_PTMX
6029#else
6030#define DEV_PTY_FILE "/dev/ptmx"
6031#endif
6032
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006033#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006034#ifdef HAVE_PTY_H
6035#include <pty.h>
6036#else
6037#ifdef HAVE_LIBUTIL_H
6038#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006039#else
6040#ifdef HAVE_UTIL_H
6041#include <util.h>
6042#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006043#endif /* HAVE_LIBUTIL_H */
6044#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006045#ifdef HAVE_STROPTS_H
6046#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006047#endif
6048#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006049
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006050#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006052"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006054
6055static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006056posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006057{
Victor Stinner8c62be82010-05-06 00:08:46 +00006058 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006059#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006061#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006062#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006063 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006064#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006066#endif
6067#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006068
Thomas Wouters70c21a12000-07-14 14:28:33 +00006069#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006070 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6071 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006072#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006073 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6074 if (slave_name == NULL)
6075 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006076
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 slave_fd = open(slave_name, O_RDWR);
6078 if (slave_fd < 0)
6079 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006080#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6082 if (master_fd < 0)
6083 return posix_error();
6084 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6085 /* change permission of slave */
6086 if (grantpt(master_fd) < 0) {
6087 PyOS_setsig(SIGCHLD, sig_saved);
6088 return posix_error();
6089 }
6090 /* unlock slave */
6091 if (unlockpt(master_fd) < 0) {
6092 PyOS_setsig(SIGCHLD, sig_saved);
6093 return posix_error();
6094 }
6095 PyOS_setsig(SIGCHLD, sig_saved);
6096 slave_name = ptsname(master_fd); /* get name of slave */
6097 if (slave_name == NULL)
6098 return posix_error();
6099 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6100 if (slave_fd < 0)
6101 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006102#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006103 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6104 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006105#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006107#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006108#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006109#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006110
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006112
Fred Drake8cef4cf2000-06-28 16:40:38 +00006113}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006114#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006115
6116#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006119Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6120Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006122
6123static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006124posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006125{
Victor Stinner8c62be82010-05-06 00:08:46 +00006126 int master_fd = -1, result = 0;
6127 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006128
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 _PyImport_AcquireLock();
6130 pid = forkpty(&master_fd, NULL, NULL, NULL);
6131 if (pid == 0) {
6132 /* child: this clobbers and resets the import lock. */
6133 PyOS_AfterFork();
6134 } else {
6135 /* parent: release the import lock. */
6136 result = _PyImport_ReleaseLock();
6137 }
6138 if (pid == -1)
6139 return posix_error();
6140 if (result < 0) {
6141 /* Don't clobber the OSError if the fork failed. */
6142 PyErr_SetString(PyExc_RuntimeError,
6143 "not holding the import lock");
6144 return NULL;
6145 }
6146 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006147}
6148#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006149
Ross Lagerwall7807c352011-03-17 20:20:30 +02006150
Guido van Rossumad0ee831995-03-01 10:34:45 +00006151#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006152PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006153"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006154Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006155
Barry Warsaw53699e91996-12-10 23:23:01 +00006156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006157posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006158{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006159 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006160}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006161#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006163
Guido van Rossumad0ee831995-03-01 10:34:45 +00006164#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006166"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006167Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006168
Barry Warsaw53699e91996-12-10 23:23:01 +00006169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006170posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006171{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006172 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006173}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006174#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006176
Guido van Rossumad0ee831995-03-01 10:34:45 +00006177#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006178PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006179"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006180Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006181
Barry Warsaw53699e91996-12-10 23:23:01 +00006182static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006183posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006184{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006185 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006186}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006187#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006190PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006191"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006192Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Barry Warsaw53699e91996-12-10 23:23:01 +00006194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006195posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006196{
Victor Stinner8c62be82010-05-06 00:08:46 +00006197 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006198}
6199
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006200#ifdef HAVE_GETGROUPLIST
6201PyDoc_STRVAR(posix_getgrouplist__doc__,
6202"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6203Returns a list of groups to which a user belongs.\n\n\
6204 user: username to lookup\n\
6205 group: base group id of the user");
6206
6207static PyObject *
6208posix_getgrouplist(PyObject *self, PyObject *args)
6209{
6210#ifdef NGROUPS_MAX
6211#define MAX_GROUPS NGROUPS_MAX
6212#else
6213 /* defined to be 16 on Solaris7, so this should be a small number */
6214#define MAX_GROUPS 64
6215#endif
6216
6217 const char *user;
6218 int i, ngroups;
6219 PyObject *list;
6220#ifdef __APPLE__
6221 int *groups, basegid;
6222#else
6223 gid_t *groups, basegid;
6224#endif
6225 ngroups = MAX_GROUPS;
6226
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006227#ifdef __APPLE__
6228 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006229 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006230#else
6231 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6232 _Py_Gid_Converter, &basegid))
6233 return NULL;
6234#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006235
6236#ifdef __APPLE__
6237 groups = PyMem_Malloc(ngroups * sizeof(int));
6238#else
6239 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6240#endif
6241 if (groups == NULL)
6242 return PyErr_NoMemory();
6243
6244 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6245 PyMem_Del(groups);
6246 return posix_error();
6247 }
6248
6249 list = PyList_New(ngroups);
6250 if (list == NULL) {
6251 PyMem_Del(groups);
6252 return NULL;
6253 }
6254
6255 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006256#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006257 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006258#else
6259 PyObject *o = _PyLong_FromGid(groups[i]);
6260#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006261 if (o == NULL) {
6262 Py_DECREF(list);
6263 PyMem_Del(groups);
6264 return NULL;
6265 }
6266 PyList_SET_ITEM(list, i, o);
6267 }
6268
6269 PyMem_Del(groups);
6270
6271 return list;
6272}
6273#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006274
Fred Drakec9680921999-12-13 16:37:25 +00006275#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006276PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006277"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006278Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006279
6280static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006281posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006282{
6283 PyObject *result = NULL;
6284
Fred Drakec9680921999-12-13 16:37:25 +00006285#ifdef NGROUPS_MAX
6286#define MAX_GROUPS NGROUPS_MAX
6287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006289#define MAX_GROUPS 64
6290#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006292
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006293 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006294 * This is a helper variable to store the intermediate result when
6295 * that happens.
6296 *
6297 * To keep the code readable the OSX behaviour is unconditional,
6298 * according to the POSIX spec this should be safe on all unix-y
6299 * systems.
6300 */
6301 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006303
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006305 if (n < 0) {
6306 if (errno == EINVAL) {
6307 n = getgroups(0, NULL);
6308 if (n == -1) {
6309 return posix_error();
6310 }
6311 if (n == 0) {
6312 /* Avoid malloc(0) */
6313 alt_grouplist = grouplist;
6314 } else {
6315 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6316 if (alt_grouplist == NULL) {
6317 errno = EINVAL;
6318 return posix_error();
6319 }
6320 n = getgroups(n, alt_grouplist);
6321 if (n == -1) {
6322 PyMem_Free(alt_grouplist);
6323 return posix_error();
6324 }
6325 }
6326 } else {
6327 return posix_error();
6328 }
6329 }
6330 result = PyList_New(n);
6331 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 int i;
6333 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006334 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006336 Py_DECREF(result);
6337 result = NULL;
6338 break;
Fred Drakec9680921999-12-13 16:37:25 +00006339 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006341 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006342 }
6343
6344 if (alt_grouplist != grouplist) {
6345 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006346 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006347
Fred Drakec9680921999-12-13 16:37:25 +00006348 return result;
6349}
6350#endif
6351
Antoine Pitroub7572f02009-12-02 20:46:48 +00006352#ifdef HAVE_INITGROUPS
6353PyDoc_STRVAR(posix_initgroups__doc__,
6354"initgroups(username, gid) -> None\n\n\
6355Call the system initgroups() to initialize the group access list with all of\n\
6356the groups of which the specified username is a member, plus the specified\n\
6357group id.");
6358
6359static PyObject *
6360posix_initgroups(PyObject *self, PyObject *args)
6361{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006362 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006364 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006365#ifdef __APPLE__
6366 int gid;
6367#else
6368 gid_t gid;
6369#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006370
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006371#ifdef __APPLE__
6372 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6373 PyUnicode_FSConverter, &oname,
6374 &gid))
6375#else
6376 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6377 PyUnicode_FSConverter, &oname,
6378 _Py_Gid_Converter, &gid))
6379#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006381 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006382
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006383 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006384 Py_DECREF(oname);
6385 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006387
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 Py_INCREF(Py_None);
6389 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006390}
6391#endif
6392
Martin v. Löwis606edc12002-06-13 21:09:11 +00006393#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006394PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006395"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006396Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006397
6398static PyObject *
6399posix_getpgid(PyObject *self, PyObject *args)
6400{
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 pid_t pid, pgid;
6402 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6403 return NULL;
6404 pgid = getpgid(pid);
6405 if (pgid < 0)
6406 return posix_error();
6407 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006408}
6409#endif /* HAVE_GETPGID */
6410
6411
Guido van Rossumb6775db1994-08-01 11:34:53 +00006412#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006413PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006414"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006415Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006416
Barry Warsaw53699e91996-12-10 23:23:01 +00006417static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006418posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006419{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006420#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006421 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006422#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006424#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006425}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006426#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006428
Guido van Rossumb6775db1994-08-01 11:34:53 +00006429#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006430PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006431"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006432Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006433
Barry Warsaw53699e91996-12-10 23:23:01 +00006434static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006435posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006436{
Guido van Rossum64933891994-10-20 21:56:42 +00006437#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006439#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006441#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006442 return posix_error();
6443 Py_INCREF(Py_None);
6444 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006445}
6446
Guido van Rossumb6775db1994-08-01 11:34:53 +00006447#endif /* HAVE_SETPGRP */
6448
Guido van Rossumad0ee831995-03-01 10:34:45 +00006449#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006450
6451#ifdef MS_WINDOWS
6452#include <tlhelp32.h>
6453
6454static PyObject*
6455win32_getppid()
6456{
6457 HANDLE snapshot;
6458 pid_t mypid;
6459 PyObject* result = NULL;
6460 BOOL have_record;
6461 PROCESSENTRY32 pe;
6462
6463 mypid = getpid(); /* This function never fails */
6464
6465 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6466 if (snapshot == INVALID_HANDLE_VALUE)
6467 return PyErr_SetFromWindowsErr(GetLastError());
6468
6469 pe.dwSize = sizeof(pe);
6470 have_record = Process32First(snapshot, &pe);
6471 while (have_record) {
6472 if (mypid == (pid_t)pe.th32ProcessID) {
6473 /* We could cache the ulong value in a static variable. */
6474 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6475 break;
6476 }
6477
6478 have_record = Process32Next(snapshot, &pe);
6479 }
6480
6481 /* If our loop exits and our pid was not found (result will be NULL)
6482 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6483 * error anyway, so let's raise it. */
6484 if (!result)
6485 result = PyErr_SetFromWindowsErr(GetLastError());
6486
6487 CloseHandle(snapshot);
6488
6489 return result;
6490}
6491#endif /*MS_WINDOWS*/
6492
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006493PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006494"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006495Return the parent's process id. If the parent process has already exited,\n\
6496Windows machines will still return its id; others systems will return the id\n\
6497of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006498
Barry Warsaw53699e91996-12-10 23:23:01 +00006499static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006500posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006501{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006502#ifdef MS_WINDOWS
6503 return win32_getppid();
6504#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006506#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006507}
6508#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006509
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006510
Fred Drake12c6e2d1999-12-14 21:25:03 +00006511#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006512PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006513"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006514Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006515
6516static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006517posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006518{
Victor Stinner8c62be82010-05-06 00:08:46 +00006519 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006520#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006521 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006522 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006523
6524 if (GetUserNameW(user_name, &num_chars)) {
6525 /* num_chars is the number of unicode chars plus null terminator */
6526 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006527 }
6528 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006529 result = PyErr_SetFromWindowsErr(GetLastError());
6530#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006531 char *name;
6532 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006533
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 errno = 0;
6535 name = getlogin();
6536 if (name == NULL) {
6537 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006538 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006539 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006540 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006541 }
6542 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006543 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006545#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006546 return result;
6547}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006548#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006549
Guido van Rossumad0ee831995-03-01 10:34:45 +00006550#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006551PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006552"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006554
Barry Warsaw53699e91996-12-10 23:23:01 +00006555static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006556posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006557{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006558 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006559}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006560#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006562
Guido van Rossumad0ee831995-03-01 10:34:45 +00006563#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006564PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006565"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006566Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006567
Barry Warsaw53699e91996-12-10 23:23:01 +00006568static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006569posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006570{
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 pid_t pid;
6572 int sig;
6573 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6574 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006575#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006576 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6577 APIRET rc;
6578 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006579 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006580
6581 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6582 APIRET rc;
6583 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006584 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006585
6586 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006587 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006588#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 if (kill(pid, sig) == -1)
6590 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006591#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 Py_INCREF(Py_None);
6593 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006594}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006595#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006596
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006597#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006598PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006599"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006600Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006601
6602static PyObject *
6603posix_killpg(PyObject *self, PyObject *args)
6604{
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 int sig;
6606 pid_t pgid;
6607 /* XXX some man pages make the `pgid` parameter an int, others
6608 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6609 take the same type. Moreover, pid_t is always at least as wide as
6610 int (else compilation of this module fails), which is safe. */
6611 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6612 return NULL;
6613 if (killpg(pgid, sig) == -1)
6614 return posix_error();
6615 Py_INCREF(Py_None);
6616 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006617}
6618#endif
6619
Brian Curtineb24d742010-04-12 17:16:38 +00006620#ifdef MS_WINDOWS
6621PyDoc_STRVAR(win32_kill__doc__,
6622"kill(pid, sig)\n\n\
6623Kill a process with a signal.");
6624
6625static PyObject *
6626win32_kill(PyObject *self, PyObject *args)
6627{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006628 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 DWORD pid, sig, err;
6630 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006631
Victor Stinner8c62be82010-05-06 00:08:46 +00006632 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6633 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006634
Victor Stinner8c62be82010-05-06 00:08:46 +00006635 /* Console processes which share a common console can be sent CTRL+C or
6636 CTRL+BREAK events, provided they handle said events. */
6637 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6638 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6639 err = GetLastError();
6640 PyErr_SetFromWindowsErr(err);
6641 }
6642 else
6643 Py_RETURN_NONE;
6644 }
Brian Curtineb24d742010-04-12 17:16:38 +00006645
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6647 attempt to open and terminate the process. */
6648 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6649 if (handle == NULL) {
6650 err = GetLastError();
6651 return PyErr_SetFromWindowsErr(err);
6652 }
Brian Curtineb24d742010-04-12 17:16:38 +00006653
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 if (TerminateProcess(handle, sig) == 0) {
6655 err = GetLastError();
6656 result = PyErr_SetFromWindowsErr(err);
6657 } else {
6658 Py_INCREF(Py_None);
6659 result = Py_None;
6660 }
Brian Curtineb24d742010-04-12 17:16:38 +00006661
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 CloseHandle(handle);
6663 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006664}
6665#endif /* MS_WINDOWS */
6666
Guido van Rossumc0125471996-06-28 18:55:32 +00006667#ifdef HAVE_PLOCK
6668
6669#ifdef HAVE_SYS_LOCK_H
6670#include <sys/lock.h>
6671#endif
6672
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006673PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006674"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006675Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006676
Barry Warsaw53699e91996-12-10 23:23:01 +00006677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006678posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006679{
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 int op;
6681 if (!PyArg_ParseTuple(args, "i:plock", &op))
6682 return NULL;
6683 if (plock(op) == -1)
6684 return posix_error();
6685 Py_INCREF(Py_None);
6686 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006687}
6688#endif
6689
Guido van Rossumb6775db1994-08-01 11:34:53 +00006690#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006692"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006693Set the current process's user id.");
6694
Barry Warsaw53699e91996-12-10 23:23:01 +00006695static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006696posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006697{
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006699 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 if (setuid(uid) < 0)
6702 return posix_error();
6703 Py_INCREF(Py_None);
6704 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006705}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006706#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006707
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006708
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006709#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006710PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006711"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006712Set the current process's effective user id.");
6713
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006714static PyObject *
6715posix_seteuid (PyObject *self, PyObject *args)
6716{
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006718 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006720 if (seteuid(euid) < 0) {
6721 return posix_error();
6722 } else {
6723 Py_INCREF(Py_None);
6724 return Py_None;
6725 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006726}
6727#endif /* HAVE_SETEUID */
6728
6729#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006730PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006731"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006732Set the current process's effective group id.");
6733
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006734static PyObject *
6735posix_setegid (PyObject *self, PyObject *args)
6736{
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006738 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 if (setegid(egid) < 0) {
6741 return posix_error();
6742 } else {
6743 Py_INCREF(Py_None);
6744 return Py_None;
6745 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006746}
6747#endif /* HAVE_SETEGID */
6748
6749#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006750PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006751"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752Set the current process's real and effective user ids.");
6753
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006754static PyObject *
6755posix_setreuid (PyObject *self, PyObject *args)
6756{
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006758 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6759 _Py_Uid_Converter, &ruid,
6760 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 if (setreuid(ruid, euid) < 0) {
6763 return posix_error();
6764 } else {
6765 Py_INCREF(Py_None);
6766 return Py_None;
6767 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006768}
6769#endif /* HAVE_SETREUID */
6770
6771#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006772PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006773"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006774Set the current process's real and effective group ids.");
6775
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006776static PyObject *
6777posix_setregid (PyObject *self, PyObject *args)
6778{
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006780 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6781 _Py_Gid_Converter, &rgid,
6782 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 if (setregid(rgid, egid) < 0) {
6785 return posix_error();
6786 } else {
6787 Py_INCREF(Py_None);
6788 return Py_None;
6789 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006790}
6791#endif /* HAVE_SETREGID */
6792
Guido van Rossumb6775db1994-08-01 11:34:53 +00006793#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006794PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006795"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006796Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006797
Barry Warsaw53699e91996-12-10 23:23:01 +00006798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006799posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006800{
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006802 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 if (setgid(gid) < 0)
6805 return posix_error();
6806 Py_INCREF(Py_None);
6807 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006808}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006809#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006810
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006811#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006813"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006815
6816static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006817posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006818{
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 int i, len;
6820 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006821
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 if (!PySequence_Check(groups)) {
6823 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6824 return NULL;
6825 }
6826 len = PySequence_Size(groups);
6827 if (len > MAX_GROUPS) {
6828 PyErr_SetString(PyExc_ValueError, "too many groups");
6829 return NULL;
6830 }
6831 for(i = 0; i < len; i++) {
6832 PyObject *elem;
6833 elem = PySequence_GetItem(groups, i);
6834 if (!elem)
6835 return NULL;
6836 if (!PyLong_Check(elem)) {
6837 PyErr_SetString(PyExc_TypeError,
6838 "groups must be integers");
6839 Py_DECREF(elem);
6840 return NULL;
6841 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006842 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 Py_DECREF(elem);
6844 return NULL;
6845 }
6846 }
6847 Py_DECREF(elem);
6848 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006849
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 if (setgroups(len, grouplist) < 0)
6851 return posix_error();
6852 Py_INCREF(Py_None);
6853 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006854}
6855#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006856
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6858static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006859wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006860{
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 PyObject *result;
6862 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006863 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006864
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 if (pid == -1)
6866 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006867
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 if (struct_rusage == NULL) {
6869 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6870 if (m == NULL)
6871 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006872 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 Py_DECREF(m);
6874 if (struct_rusage == NULL)
6875 return NULL;
6876 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6879 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6880 if (!result)
6881 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882
6883#ifndef doubletime
6884#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6885#endif
6886
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006888 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006890 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6893 SET_INT(result, 2, ru->ru_maxrss);
6894 SET_INT(result, 3, ru->ru_ixrss);
6895 SET_INT(result, 4, ru->ru_idrss);
6896 SET_INT(result, 5, ru->ru_isrss);
6897 SET_INT(result, 6, ru->ru_minflt);
6898 SET_INT(result, 7, ru->ru_majflt);
6899 SET_INT(result, 8, ru->ru_nswap);
6900 SET_INT(result, 9, ru->ru_inblock);
6901 SET_INT(result, 10, ru->ru_oublock);
6902 SET_INT(result, 11, ru->ru_msgsnd);
6903 SET_INT(result, 12, ru->ru_msgrcv);
6904 SET_INT(result, 13, ru->ru_nsignals);
6905 SET_INT(result, 14, ru->ru_nvcsw);
6906 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907#undef SET_INT
6908
Victor Stinner8c62be82010-05-06 00:08:46 +00006909 if (PyErr_Occurred()) {
6910 Py_DECREF(result);
6911 return NULL;
6912 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915}
6916#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6917
6918#ifdef HAVE_WAIT3
6919PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006920"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006921Wait for completion of a child process.");
6922
6923static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006924posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925{
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 pid_t pid;
6927 int options;
6928 struct rusage ru;
6929 WAIT_TYPE status;
6930 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931
Victor Stinner4195b5c2012-02-08 23:03:19 +01006932 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006933 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 Py_BEGIN_ALLOW_THREADS
6936 pid = wait3(&status, options, &ru);
6937 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006938
Victor Stinner4195b5c2012-02-08 23:03:19 +01006939 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006940}
6941#endif /* HAVE_WAIT3 */
6942
6943#ifdef HAVE_WAIT4
6944PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006945"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006946Wait for completion of a given child process.");
6947
6948static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006949posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950{
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 pid_t pid;
6952 int options;
6953 struct rusage ru;
6954 WAIT_TYPE status;
6955 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006956
Victor Stinner4195b5c2012-02-08 23:03:19 +01006957 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006959
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 Py_BEGIN_ALLOW_THREADS
6961 pid = wait4(pid, &status, options, &ru);
6962 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006963
Victor Stinner4195b5c2012-02-08 23:03:19 +01006964 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006965}
6966#endif /* HAVE_WAIT4 */
6967
Ross Lagerwall7807c352011-03-17 20:20:30 +02006968#if defined(HAVE_WAITID) && !defined(__APPLE__)
6969PyDoc_STRVAR(posix_waitid__doc__,
6970"waitid(idtype, id, options) -> waitid_result\n\n\
6971Wait for the completion of one or more child processes.\n\n\
6972idtype can be P_PID, P_PGID or P_ALL.\n\
6973id specifies the pid to wait on.\n\
6974options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6975or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6976Returns either waitid_result or None if WNOHANG is specified and there are\n\
6977no children in a waitable state.");
6978
6979static PyObject *
6980posix_waitid(PyObject *self, PyObject *args)
6981{
6982 PyObject *result;
6983 idtype_t idtype;
6984 id_t id;
6985 int options, res;
6986 siginfo_t si;
6987 si.si_pid = 0;
6988 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6989 return NULL;
6990 Py_BEGIN_ALLOW_THREADS
6991 res = waitid(idtype, id, &si, options);
6992 Py_END_ALLOW_THREADS
6993 if (res == -1)
6994 return posix_error();
6995
6996 if (si.si_pid == 0)
6997 Py_RETURN_NONE;
6998
6999 result = PyStructSequence_New(&WaitidResultType);
7000 if (!result)
7001 return NULL;
7002
7003 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007004 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007005 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7006 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7007 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7008 if (PyErr_Occurred()) {
7009 Py_DECREF(result);
7010 return NULL;
7011 }
7012
7013 return result;
7014}
7015#endif
7016
Guido van Rossumb6775db1994-08-01 11:34:53 +00007017#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007018PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007019"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007020Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007021
Barry Warsaw53699e91996-12-10 23:23:01 +00007022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007023posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007024{
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 pid_t pid;
7026 int options;
7027 WAIT_TYPE status;
7028 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007029
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7031 return NULL;
7032 Py_BEGIN_ALLOW_THREADS
7033 pid = waitpid(pid, &status, options);
7034 Py_END_ALLOW_THREADS
7035 if (pid == -1)
7036 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007037
Victor Stinner8c62be82010-05-06 00:08:46 +00007038 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007039}
7040
Tim Petersab034fa2002-02-01 11:27:43 +00007041#elif defined(HAVE_CWAIT)
7042
7043/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007044PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007045"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007046"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007047
7048static PyObject *
7049posix_waitpid(PyObject *self, PyObject *args)
7050{
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 Py_intptr_t pid;
7052 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007053
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7055 return NULL;
7056 Py_BEGIN_ALLOW_THREADS
7057 pid = _cwait(&status, pid, options);
7058 Py_END_ALLOW_THREADS
7059 if (pid == -1)
7060 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007061
Victor Stinner8c62be82010-05-06 00:08:46 +00007062 /* shift the status left a byte so this is more like the POSIX waitpid */
7063 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007064}
7065#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007066
Guido van Rossumad0ee831995-03-01 10:34:45 +00007067#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007068PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007069"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007070Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007071
Barry Warsaw53699e91996-12-10 23:23:01 +00007072static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007073posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007074{
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 pid_t pid;
7076 WAIT_TYPE status;
7077 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007078
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 Py_BEGIN_ALLOW_THREADS
7080 pid = wait(&status);
7081 Py_END_ALLOW_THREADS
7082 if (pid == -1)
7083 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007084
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007086}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007087#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007089
Larry Hastings9cf065c2012-06-22 16:30:09 -07007090#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7091PyDoc_STRVAR(readlink__doc__,
7092"readlink(path, *, dir_fd=None) -> path\n\n\
7093Return a string representing the path to which the symbolic link points.\n\
7094\n\
7095If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7096 and path should be relative; path will then be relative to that directory.\n\
7097dir_fd may not be implemented on your platform.\n\
7098 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007099#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007100
Guido van Rossumb6775db1994-08-01 11:34:53 +00007101#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007102
Barry Warsaw53699e91996-12-10 23:23:01 +00007103static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007104posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106 path_t path;
7107 int dir_fd = DEFAULT_DIR_FD;
7108 char buffer[MAXPATHLEN];
7109 ssize_t length;
7110 PyObject *return_value = NULL;
7111 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007112
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113 memset(&path, 0, sizeof(path));
7114 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7115 path_converter, &path,
7116#ifdef HAVE_READLINKAT
7117 dir_fd_converter, &dir_fd
7118#else
7119 dir_fd_unavailable, &dir_fd
7120#endif
7121 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007123
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125#ifdef HAVE_READLINKAT
7126 if (dir_fd != DEFAULT_DIR_FD)
7127 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007128 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007129#endif
7130 length = readlink(path.narrow, buffer, sizeof(buffer));
7131 Py_END_ALLOW_THREADS
7132
7133 if (length < 0) {
7134 return_value = path_posix_error("readlink", &path);
7135 goto exit;
7136 }
7137
7138 if (PyUnicode_Check(path.object))
7139 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7140 else
7141 return_value = PyBytes_FromStringAndSize(buffer, length);
7142exit:
7143 path_cleanup(&path);
7144 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007145}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007146
7147
Guido van Rossumb6775db1994-08-01 11:34:53 +00007148#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007149
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007150
Larry Hastings9cf065c2012-06-22 16:30:09 -07007151#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007152PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007153"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7154Create a symbolic link pointing to src named dst.\n\n\
7155target_is_directory is required on Windows if the target is to be\n\
7156 interpreted as a directory. (On Windows, symlink requires\n\
7157 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7158 target_is_directory is ignored on non-Windows platforms.\n\
7159\n\
7160If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7161 and path should be relative; path will then be relative to that directory.\n\
7162dir_fd may not be implemented on your platform.\n\
7163 If it is unavailable, using it will raise a NotImplementedError.");
7164
7165#if defined(MS_WINDOWS)
7166
7167/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7168static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7169static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7170static int
7171check_CreateSymbolicLink()
7172{
7173 HINSTANCE hKernel32;
7174 /* only recheck */
7175 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7176 return 1;
7177 hKernel32 = GetModuleHandleW(L"KERNEL32");
7178 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7179 "CreateSymbolicLinkW");
7180 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7181 "CreateSymbolicLinkA");
7182 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7183}
7184
7185#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007186
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007187static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007188posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007189{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190 path_t src;
7191 path_t dst;
7192 int dir_fd = DEFAULT_DIR_FD;
7193 int target_is_directory = 0;
7194 static char *keywords[] = {"src", "dst", "target_is_directory",
7195 "dir_fd", NULL};
7196 PyObject *return_value;
7197#ifdef MS_WINDOWS
7198 DWORD result;
7199#else
7200 int result;
7201#endif
7202
7203 memset(&src, 0, sizeof(src));
7204 src.argument_name = "src";
7205 memset(&dst, 0, sizeof(dst));
7206 dst.argument_name = "dst";
7207
7208#ifdef MS_WINDOWS
7209 if (!check_CreateSymbolicLink()) {
7210 PyErr_SetString(PyExc_NotImplementedError,
7211 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007212 return NULL;
7213 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007214 if (!win32_can_symlink) {
7215 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007216 return NULL;
7217 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007218#endif
7219
7220 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7221 keywords,
7222 path_converter, &src,
7223 path_converter, &dst,
7224 &target_is_directory,
7225#ifdef HAVE_SYMLINKAT
7226 dir_fd_converter, &dir_fd
7227#else
7228 dir_fd_unavailable, &dir_fd
7229#endif
7230 ))
7231 return NULL;
7232
7233 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7234 PyErr_SetString(PyExc_ValueError,
7235 "symlink: src and dst must be the same type");
7236 return_value = NULL;
7237 goto exit;
7238 }
7239
7240#ifdef MS_WINDOWS
7241 Py_BEGIN_ALLOW_THREADS
7242 if (dst.wide)
7243 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7244 target_is_directory);
7245 else
7246 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7247 target_is_directory);
7248 Py_END_ALLOW_THREADS
7249
7250 if (!result) {
7251 return_value = win32_error_object("symlink", src.object);
7252 goto exit;
7253 }
7254
7255#else
7256
7257 Py_BEGIN_ALLOW_THREADS
7258#if HAVE_SYMLINKAT
7259 if (dir_fd != DEFAULT_DIR_FD)
7260 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7261 else
7262#endif
7263 result = symlink(src.narrow, dst.narrow);
7264 Py_END_ALLOW_THREADS
7265
7266 if (result) {
7267 return_value = path_error("symlink", &dst);
7268 goto exit;
7269 }
7270#endif
7271
7272 return_value = Py_None;
7273 Py_INCREF(Py_None);
7274 goto exit; /* silence "unused label" warning */
7275exit:
7276 path_cleanup(&src);
7277 path_cleanup(&dst);
7278 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007279}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007280
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007281#endif /* HAVE_SYMLINK */
7282
Larry Hastings9cf065c2012-06-22 16:30:09 -07007283
Brian Curtind40e6f72010-07-08 21:39:08 +00007284#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7285
Brian Curtind40e6f72010-07-08 21:39:08 +00007286static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007287win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007288{
7289 wchar_t *path;
7290 DWORD n_bytes_returned;
7291 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007292 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007293 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007294 HANDLE reparse_point_handle;
7295
7296 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7297 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7298 wchar_t *print_name;
7299
Larry Hastings9cf065c2012-06-22 16:30:09 -07007300 static char *keywords[] = {"path", "dir_fd", NULL};
7301
7302 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7303 &po,
7304 dir_fd_unavailable, &dir_fd
7305 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007306 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007307
Victor Stinnereb5657a2011-09-30 01:44:27 +02007308 path = PyUnicode_AsUnicode(po);
7309 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007310 return NULL;
7311
7312 /* First get a handle to the reparse point */
7313 Py_BEGIN_ALLOW_THREADS
7314 reparse_point_handle = CreateFileW(
7315 path,
7316 0,
7317 0,
7318 0,
7319 OPEN_EXISTING,
7320 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7321 0);
7322 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007323
Brian Curtind40e6f72010-07-08 21:39:08 +00007324 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007325 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007326
Brian Curtind40e6f72010-07-08 21:39:08 +00007327 Py_BEGIN_ALLOW_THREADS
7328 /* New call DeviceIoControl to read the reparse point */
7329 io_result = DeviceIoControl(
7330 reparse_point_handle,
7331 FSCTL_GET_REPARSE_POINT,
7332 0, 0, /* in buffer */
7333 target_buffer, sizeof(target_buffer),
7334 &n_bytes_returned,
7335 0 /* we're not using OVERLAPPED_IO */
7336 );
7337 CloseHandle(reparse_point_handle);
7338 Py_END_ALLOW_THREADS
7339
7340 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007341 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007342
7343 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7344 {
7345 PyErr_SetString(PyExc_ValueError,
7346 "not a symbolic link");
7347 return NULL;
7348 }
Brian Curtin74e45612010-07-09 15:58:59 +00007349 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7350 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7351
7352 result = PyUnicode_FromWideChar(print_name,
7353 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007354 return result;
7355}
7356
7357#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7358
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007359
Larry Hastings605a62d2012-06-24 04:33:36 -07007360static PyStructSequence_Field times_result_fields[] = {
7361 {"user", "user time"},
7362 {"system", "system time"},
7363 {"children_user", "user time of children"},
7364 {"children_system", "system time of children"},
7365 {"elapsed", "elapsed time since an arbitrary point in the past"},
7366 {NULL}
7367};
7368
7369PyDoc_STRVAR(times_result__doc__,
7370"times_result: Result from os.times().\n\n\
7371This object may be accessed either as a tuple of\n\
7372 (user, system, children_user, children_system, elapsed),\n\
7373or via the attributes user, system, children_user, children_system,\n\
7374and elapsed.\n\
7375\n\
7376See os.times for more information.");
7377
7378static PyStructSequence_Desc times_result_desc = {
7379 "times_result", /* name */
7380 times_result__doc__, /* doc */
7381 times_result_fields,
7382 5
7383};
7384
7385static PyTypeObject TimesResultType;
7386
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007387#ifdef MS_WINDOWS
7388#define HAVE_TIMES /* mandatory, for the method table */
7389#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007390
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007391#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007392
7393static PyObject *
7394build_times_result(double user, double system,
7395 double children_user, double children_system,
7396 double elapsed)
7397{
7398 PyObject *value = PyStructSequence_New(&TimesResultType);
7399 if (value == NULL)
7400 return NULL;
7401
7402#define SET(i, field) \
7403 { \
7404 PyObject *o = PyFloat_FromDouble(field); \
7405 if (!o) { \
7406 Py_DECREF(value); \
7407 return NULL; \
7408 } \
7409 PyStructSequence_SET_ITEM(value, i, o); \
7410 } \
7411
7412 SET(0, user);
7413 SET(1, system);
7414 SET(2, children_user);
7415 SET(3, children_system);
7416 SET(4, elapsed);
7417
7418#undef SET
7419
7420 return value;
7421}
7422
7423PyDoc_STRVAR(posix_times__doc__,
7424"times() -> times_result\n\n\
7425Return an object containing floating point numbers indicating process\n\
7426times. The object behaves like a named tuple with these fields:\n\
7427 (utime, stime, cutime, cstime, elapsed_time)");
7428
Guido van Rossumd48f2521997-12-05 22:19:34 +00007429#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7430static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007431system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007432{
7433 ULONG value = 0;
7434
7435 Py_BEGIN_ALLOW_THREADS
7436 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7437 Py_END_ALLOW_THREADS
7438
7439 return value;
7440}
7441
7442static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007443posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007444{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007445 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007446 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007447 (double)0 /* t.tms_utime / HZ */,
7448 (double)0 /* t.tms_stime / HZ */,
7449 (double)0 /* t.tms_cutime / HZ */,
7450 (double)0 /* t.tms_cstime / HZ */,
7451 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007452}
Larry Hastings605a62d2012-06-24 04:33:36 -07007453#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007454static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007455posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007456{
Victor Stinner8c62be82010-05-06 00:08:46 +00007457 FILETIME create, exit, kernel, user;
7458 HANDLE hProc;
7459 hProc = GetCurrentProcess();
7460 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7461 /* The fields of a FILETIME structure are the hi and lo part
7462 of a 64-bit value expressed in 100 nanosecond units.
7463 1e7 is one second in such units; 1e-7 the inverse.
7464 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7465 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007466 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 (double)(user.dwHighDateTime*429.4967296 +
7468 user.dwLowDateTime*1e-7),
7469 (double)(kernel.dwHighDateTime*429.4967296 +
7470 kernel.dwLowDateTime*1e-7),
7471 (double)0,
7472 (double)0,
7473 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007474}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007475#else /* Neither Windows nor OS/2 */
7476#define NEED_TICKS_PER_SECOND
7477static long ticks_per_second = -1;
7478static PyObject *
7479posix_times(PyObject *self, PyObject *noargs)
7480{
7481 struct tms t;
7482 clock_t c;
7483 errno = 0;
7484 c = times(&t);
7485 if (c == (clock_t) -1)
7486 return posix_error();
7487 return build_times_result(
7488 (double)t.tms_utime / ticks_per_second,
7489 (double)t.tms_stime / ticks_per_second,
7490 (double)t.tms_cutime / ticks_per_second,
7491 (double)t.tms_cstime / ticks_per_second,
7492 (double)c / ticks_per_second);
7493}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007494#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007495
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007496#endif /* HAVE_TIMES */
7497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007498
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007499#ifdef HAVE_GETSID
7500PyDoc_STRVAR(posix_getsid__doc__,
7501"getsid(pid) -> sid\n\n\
7502Call the system call getsid().");
7503
7504static PyObject *
7505posix_getsid(PyObject *self, PyObject *args)
7506{
Victor Stinner8c62be82010-05-06 00:08:46 +00007507 pid_t pid;
7508 int sid;
7509 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7510 return NULL;
7511 sid = getsid(pid);
7512 if (sid < 0)
7513 return posix_error();
7514 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007515}
7516#endif /* HAVE_GETSID */
7517
7518
Guido van Rossumb6775db1994-08-01 11:34:53 +00007519#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007520PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007521"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007522Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007523
Barry Warsaw53699e91996-12-10 23:23:01 +00007524static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007525posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007526{
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 if (setsid() < 0)
7528 return posix_error();
7529 Py_INCREF(Py_None);
7530 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007531}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007532#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007533
Guido van Rossumb6775db1994-08-01 11:34:53 +00007534#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007535PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007536"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007537Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007538
Barry Warsaw53699e91996-12-10 23:23:01 +00007539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007540posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007541{
Victor Stinner8c62be82010-05-06 00:08:46 +00007542 pid_t pid;
7543 int pgrp;
7544 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7545 return NULL;
7546 if (setpgid(pid, pgrp) < 0)
7547 return posix_error();
7548 Py_INCREF(Py_None);
7549 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007550}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007551#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007552
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007553
Guido van Rossumb6775db1994-08-01 11:34:53 +00007554#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007555PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007556"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007557Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007558
Barry Warsaw53699e91996-12-10 23:23:01 +00007559static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007560posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007561{
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 int fd;
7563 pid_t pgid;
7564 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7565 return NULL;
7566 pgid = tcgetpgrp(fd);
7567 if (pgid < 0)
7568 return posix_error();
7569 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007570}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007571#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007572
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007573
Guido van Rossumb6775db1994-08-01 11:34:53 +00007574#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007575PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007576"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007577Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007578
Barry Warsaw53699e91996-12-10 23:23:01 +00007579static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007580posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007581{
Victor Stinner8c62be82010-05-06 00:08:46 +00007582 int fd;
7583 pid_t pgid;
7584 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7585 return NULL;
7586 if (tcsetpgrp(fd, pgid) < 0)
7587 return posix_error();
7588 Py_INCREF(Py_None);
7589 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007590}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007591#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007592
Guido van Rossum687dd131993-05-17 08:34:16 +00007593/* Functions acting on file descriptors */
7594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007595PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007596"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7597Open a file for low level IO. Returns a file handle (integer).\n\
7598\n\
7599If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7600 and path should be relative; path will then be relative to that directory.\n\
7601dir_fd may not be implemented on your platform.\n\
7602 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007603
Barry Warsaw53699e91996-12-10 23:23:01 +00007604static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007605posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007606{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007607 path_t path;
7608 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007610 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007611 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007612 PyObject *return_value = NULL;
7613 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007614
Larry Hastings9cf065c2012-06-22 16:30:09 -07007615 memset(&path, 0, sizeof(path));
7616 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7617 path_converter, &path,
7618 &flags, &mode,
7619#ifdef HAVE_OPENAT
7620 dir_fd_converter, &dir_fd
7621#else
7622 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007623#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007624 ))
7625 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007626
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007628#ifdef MS_WINDOWS
7629 if (path.wide)
7630 fd = _wopen(path.wide, flags, mode);
7631 else
7632#endif
7633#ifdef HAVE_OPENAT
7634 if (dir_fd != DEFAULT_DIR_FD)
7635 fd = openat(dir_fd, path.narrow, flags, mode);
7636 else
7637#endif
7638 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007640
Larry Hastings9cf065c2012-06-22 16:30:09 -07007641 if (fd == -1) {
7642#ifdef MS_WINDOWS
7643 /* force use of posix_error here for exact backwards compatibility */
7644 if (path.wide)
7645 return_value = posix_error();
7646 else
7647#endif
7648 return_value = path_error("open", &path);
7649 goto exit;
7650 }
7651
7652 return_value = PyLong_FromLong((long)fd);
7653
7654exit:
7655 path_cleanup(&path);
7656 return return_value;
7657}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007658
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007659PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007660"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007661Close a file descriptor (for low level IO).");
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_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007665{
Victor Stinner8c62be82010-05-06 00:08:46 +00007666 int fd, res;
7667 if (!PyArg_ParseTuple(args, "i:close", &fd))
7668 return NULL;
7669 if (!_PyVerify_fd(fd))
7670 return posix_error();
7671 Py_BEGIN_ALLOW_THREADS
7672 res = close(fd);
7673 Py_END_ALLOW_THREADS
7674 if (res < 0)
7675 return posix_error();
7676 Py_INCREF(Py_None);
7677 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007678}
7679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007680
Victor Stinner8c62be82010-05-06 00:08:46 +00007681PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007682"closerange(fd_low, fd_high)\n\n\
7683Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7684
7685static PyObject *
7686posix_closerange(PyObject *self, PyObject *args)
7687{
Victor Stinner8c62be82010-05-06 00:08:46 +00007688 int fd_from, fd_to, i;
7689 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7690 return NULL;
7691 Py_BEGIN_ALLOW_THREADS
7692 for (i = fd_from; i < fd_to; i++)
7693 if (_PyVerify_fd(i))
7694 close(i);
7695 Py_END_ALLOW_THREADS
7696 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007697}
7698
7699
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007700PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007701"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007702Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007703
Barry Warsaw53699e91996-12-10 23:23:01 +00007704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007705posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007706{
Victor Stinner8c62be82010-05-06 00:08:46 +00007707 int fd;
7708 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7709 return NULL;
7710 if (!_PyVerify_fd(fd))
7711 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 if (fd < 0)
7714 return posix_error();
7715 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007716}
7717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007718
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007719PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007720"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007721Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007722
Barry Warsaw53699e91996-12-10 23:23:01 +00007723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007724posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007725{
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 int fd, fd2, res;
7727 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7728 return NULL;
7729 if (!_PyVerify_fd_dup2(fd, fd2))
7730 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 if (res < 0)
7733 return posix_error();
7734 Py_INCREF(Py_None);
7735 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007736}
7737
Ross Lagerwall7807c352011-03-17 20:20:30 +02007738#ifdef HAVE_LOCKF
7739PyDoc_STRVAR(posix_lockf__doc__,
7740"lockf(fd, cmd, len)\n\n\
7741Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7742fd is an open file descriptor.\n\
7743cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7744F_TEST.\n\
7745len specifies the section of the file to lock.");
7746
7747static PyObject *
7748posix_lockf(PyObject *self, PyObject *args)
7749{
7750 int fd, cmd, res;
7751 off_t len;
7752 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7753 &fd, &cmd, _parse_off_t, &len))
7754 return NULL;
7755
7756 Py_BEGIN_ALLOW_THREADS
7757 res = lockf(fd, cmd, len);
7758 Py_END_ALLOW_THREADS
7759
7760 if (res < 0)
7761 return posix_error();
7762
7763 Py_RETURN_NONE;
7764}
7765#endif
7766
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007767
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007768PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007769"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007770Set the current position of a file descriptor.\n\
7771Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007772
Barry Warsaw53699e91996-12-10 23:23:01 +00007773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007774posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007775{
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007777#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007779#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007781#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007782 PyObject *posobj;
7783 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007785#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7787 switch (how) {
7788 case 0: how = SEEK_SET; break;
7789 case 1: how = SEEK_CUR; break;
7790 case 2: how = SEEK_END; break;
7791 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007792#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007793
Ross Lagerwall8e749672011-03-17 21:54:07 +02007794#if !defined(HAVE_LARGEFILE_SUPPORT)
7795 pos = PyLong_AsLong(posobj);
7796#else
7797 pos = PyLong_AsLongLong(posobj);
7798#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 if (PyErr_Occurred())
7800 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007801
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 if (!_PyVerify_fd(fd))
7803 return posix_error();
7804 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007805#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007807#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007808 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007809#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 Py_END_ALLOW_THREADS
7811 if (res < 0)
7812 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007813
7814#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007816#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007818#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007819}
7820
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007821
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007822PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007823"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007824Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007825
Barry Warsaw53699e91996-12-10 23:23:01 +00007826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007827posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007828{
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 int fd, size;
7830 Py_ssize_t n;
7831 PyObject *buffer;
7832 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7833 return NULL;
7834 if (size < 0) {
7835 errno = EINVAL;
7836 return posix_error();
7837 }
7838 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7839 if (buffer == NULL)
7840 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007841 if (!_PyVerify_fd(fd)) {
7842 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007844 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 Py_BEGIN_ALLOW_THREADS
7846 n = read(fd, PyBytes_AS_STRING(buffer), size);
7847 Py_END_ALLOW_THREADS
7848 if (n < 0) {
7849 Py_DECREF(buffer);
7850 return posix_error();
7851 }
7852 if (n != size)
7853 _PyBytes_Resize(&buffer, n);
7854 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007855}
7856
Ross Lagerwall7807c352011-03-17 20:20:30 +02007857#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7858 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007859static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007860iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7861{
7862 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007863 Py_ssize_t blen, total = 0;
7864
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007865 *iov = PyMem_New(struct iovec, cnt);
7866 if (*iov == NULL) {
7867 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007868 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007869 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007870
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007871 *buf = PyMem_New(Py_buffer, cnt);
7872 if (*buf == NULL) {
7873 PyMem_Del(*iov);
7874 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007875 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007876 }
7877
7878 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007879 PyObject *item = PySequence_GetItem(seq, i);
7880 if (item == NULL)
7881 goto fail;
7882 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7883 Py_DECREF(item);
7884 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007885 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007886 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007887 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007888 blen = (*buf)[i].len;
7889 (*iov)[i].iov_len = blen;
7890 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007891 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007892 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007893
7894fail:
7895 PyMem_Del(*iov);
7896 for (j = 0; j < i; j++) {
7897 PyBuffer_Release(&(*buf)[j]);
7898 }
7899 PyMem_Del(*buf);
7900 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007901}
7902
7903static void
7904iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7905{
7906 int i;
7907 PyMem_Del(iov);
7908 for (i = 0; i < cnt; i++) {
7909 PyBuffer_Release(&buf[i]);
7910 }
7911 PyMem_Del(buf);
7912}
7913#endif
7914
Ross Lagerwall7807c352011-03-17 20:20:30 +02007915#ifdef HAVE_READV
7916PyDoc_STRVAR(posix_readv__doc__,
7917"readv(fd, buffers) -> bytesread\n\n\
7918Read from a file descriptor into a number of writable buffers. buffers\n\
7919is an arbitrary sequence of writable buffers.\n\
7920Returns the total number of bytes read.");
7921
7922static PyObject *
7923posix_readv(PyObject *self, PyObject *args)
7924{
7925 int fd, cnt;
7926 Py_ssize_t n;
7927 PyObject *seq;
7928 struct iovec *iov;
7929 Py_buffer *buf;
7930
7931 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7932 return NULL;
7933 if (!PySequence_Check(seq)) {
7934 PyErr_SetString(PyExc_TypeError,
7935 "readv() arg 2 must be a sequence");
7936 return NULL;
7937 }
7938 cnt = PySequence_Size(seq);
7939
7940 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7941 return NULL;
7942
7943 Py_BEGIN_ALLOW_THREADS
7944 n = readv(fd, iov, cnt);
7945 Py_END_ALLOW_THREADS
7946
7947 iov_cleanup(iov, buf, cnt);
7948 return PyLong_FromSsize_t(n);
7949}
7950#endif
7951
7952#ifdef HAVE_PREAD
7953PyDoc_STRVAR(posix_pread__doc__,
7954"pread(fd, buffersize, offset) -> string\n\n\
7955Read from a file descriptor, fd, at a position of offset. It will read up\n\
7956to buffersize number of bytes. The file offset remains unchanged.");
7957
7958static PyObject *
7959posix_pread(PyObject *self, PyObject *args)
7960{
7961 int fd, size;
7962 off_t offset;
7963 Py_ssize_t n;
7964 PyObject *buffer;
7965 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7966 return NULL;
7967
7968 if (size < 0) {
7969 errno = EINVAL;
7970 return posix_error();
7971 }
7972 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7973 if (buffer == NULL)
7974 return NULL;
7975 if (!_PyVerify_fd(fd)) {
7976 Py_DECREF(buffer);
7977 return posix_error();
7978 }
7979 Py_BEGIN_ALLOW_THREADS
7980 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7981 Py_END_ALLOW_THREADS
7982 if (n < 0) {
7983 Py_DECREF(buffer);
7984 return posix_error();
7985 }
7986 if (n != size)
7987 _PyBytes_Resize(&buffer, n);
7988 return buffer;
7989}
7990#endif
7991
7992PyDoc_STRVAR(posix_write__doc__,
7993"write(fd, string) -> byteswritten\n\n\
7994Write a string to a file descriptor.");
7995
7996static PyObject *
7997posix_write(PyObject *self, PyObject *args)
7998{
7999 Py_buffer pbuf;
8000 int fd;
8001 Py_ssize_t size, len;
8002
8003 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8004 return NULL;
8005 if (!_PyVerify_fd(fd)) {
8006 PyBuffer_Release(&pbuf);
8007 return posix_error();
8008 }
8009 len = pbuf.len;
8010 Py_BEGIN_ALLOW_THREADS
8011#if defined(MS_WIN64) || defined(MS_WINDOWS)
8012 if (len > INT_MAX)
8013 len = INT_MAX;
8014 size = write(fd, pbuf.buf, (int)len);
8015#else
8016 size = write(fd, pbuf.buf, len);
8017#endif
8018 Py_END_ALLOW_THREADS
8019 PyBuffer_Release(&pbuf);
8020 if (size < 0)
8021 return posix_error();
8022 return PyLong_FromSsize_t(size);
8023}
8024
8025#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008026PyDoc_STRVAR(posix_sendfile__doc__,
8027"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8028sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8029 -> byteswritten\n\
8030Copy nbytes bytes from file descriptor in to file descriptor out.");
8031
8032static PyObject *
8033posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8034{
8035 int in, out;
8036 Py_ssize_t ret;
8037 off_t offset;
8038
8039#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8040#ifndef __APPLE__
8041 Py_ssize_t len;
8042#endif
8043 PyObject *headers = NULL, *trailers = NULL;
8044 Py_buffer *hbuf, *tbuf;
8045 off_t sbytes;
8046 struct sf_hdtr sf;
8047 int flags = 0;
8048 sf.headers = NULL;
8049 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008050 static char *keywords[] = {"out", "in",
8051 "offset", "count",
8052 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008053
8054#ifdef __APPLE__
8055 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008056 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057#else
8058 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008059 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008060#endif
8061 &headers, &trailers, &flags))
8062 return NULL;
8063 if (headers != NULL) {
8064 if (!PySequence_Check(headers)) {
8065 PyErr_SetString(PyExc_TypeError,
8066 "sendfile() headers must be a sequence or None");
8067 return NULL;
8068 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008069 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008071 if (sf.hdr_cnt > 0 &&
8072 !(i = iov_setup(&(sf.headers), &hbuf,
8073 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008074 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008075#ifdef __APPLE__
8076 sbytes += i;
8077#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008078 }
8079 }
8080 if (trailers != NULL) {
8081 if (!PySequence_Check(trailers)) {
8082 PyErr_SetString(PyExc_TypeError,
8083 "sendfile() trailers must be a sequence or None");
8084 return NULL;
8085 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008086 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008087 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008088 if (sf.trl_cnt > 0 &&
8089 !(i = iov_setup(&(sf.trailers), &tbuf,
8090 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008091 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008092#ifdef __APPLE__
8093 sbytes += i;
8094#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095 }
8096 }
8097
8098 Py_BEGIN_ALLOW_THREADS
8099#ifdef __APPLE__
8100 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8101#else
8102 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8103#endif
8104 Py_END_ALLOW_THREADS
8105
8106 if (sf.headers != NULL)
8107 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8108 if (sf.trailers != NULL)
8109 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8110
8111 if (ret < 0) {
8112 if ((errno == EAGAIN) || (errno == EBUSY)) {
8113 if (sbytes != 0) {
8114 // some data has been sent
8115 goto done;
8116 }
8117 else {
8118 // no data has been sent; upper application is supposed
8119 // to retry on EAGAIN or EBUSY
8120 return posix_error();
8121 }
8122 }
8123 return posix_error();
8124 }
8125 goto done;
8126
8127done:
8128 #if !defined(HAVE_LARGEFILE_SUPPORT)
8129 return Py_BuildValue("l", sbytes);
8130 #else
8131 return Py_BuildValue("L", sbytes);
8132 #endif
8133
8134#else
8135 Py_ssize_t count;
8136 PyObject *offobj;
8137 static char *keywords[] = {"out", "in",
8138 "offset", "count", NULL};
8139 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8140 keywords, &out, &in, &offobj, &count))
8141 return NULL;
8142#ifdef linux
8143 if (offobj == Py_None) {
8144 Py_BEGIN_ALLOW_THREADS
8145 ret = sendfile(out, in, NULL, count);
8146 Py_END_ALLOW_THREADS
8147 if (ret < 0)
8148 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008149 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008150 }
8151#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008152 if (!_parse_off_t(offobj, &offset))
8153 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008154 Py_BEGIN_ALLOW_THREADS
8155 ret = sendfile(out, in, &offset, count);
8156 Py_END_ALLOW_THREADS
8157 if (ret < 0)
8158 return posix_error();
8159 return Py_BuildValue("n", ret);
8160#endif
8161}
8162#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008163
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008164PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008165"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008166Like stat(), but for an open file descriptor.\n\
8167Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008168
Barry Warsaw53699e91996-12-10 23:23:01 +00008169static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008170posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008171{
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 int fd;
8173 STRUCT_STAT st;
8174 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008175 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008176 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008177#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 /* on OpenVMS we must ensure that all bytes are written to the file */
8179 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008180#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 Py_BEGIN_ALLOW_THREADS
8182 res = FSTAT(fd, &st);
8183 Py_END_ALLOW_THREADS
8184 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008185#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008186 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008187#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008189#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 }
Tim Peters5aa91602002-01-30 05:46:57 +00008191
Victor Stinner4195b5c2012-02-08 23:03:19 +01008192 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008193}
8194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008195PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008196"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008197Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008198connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008199
8200static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008201posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008202{
Victor Stinner8c62be82010-05-06 00:08:46 +00008203 int fd;
8204 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8205 return NULL;
8206 if (!_PyVerify_fd(fd))
8207 return PyBool_FromLong(0);
8208 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008209}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008210
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008211#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008212PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008213"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008214Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008215
Barry Warsaw53699e91996-12-10 23:23:01 +00008216static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008217posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008218{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008219#if defined(PYOS_OS2)
8220 HFILE read, write;
8221 APIRET rc;
8222
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008223 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008224 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008225 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008226
8227 return Py_BuildValue("(ii)", read, write);
8228#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008229#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008230 int fds[2];
8231 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008233 if (res != 0)
8234 return posix_error();
8235 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008236#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008237 HANDLE read, write;
8238 int read_fd, write_fd;
8239 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008240 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 if (!ok)
8242 return win32_error("CreatePipe", NULL);
8243 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8244 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8245 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008246#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008247#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008248}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008249#endif /* HAVE_PIPE */
8250
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008251#ifdef HAVE_PIPE2
8252PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008253"pipe2(flags) -> (read_end, write_end)\n\n\
8254Create a pipe with flags set atomically.\n\
8255flags can be constructed by ORing together one or more of these values:\n\
8256O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008257");
8258
8259static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008260posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008261{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008262 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008263 int fds[2];
8264 int res;
8265
Serhiy Storchaka9101e232013-01-19 12:41:45 +02008266 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008267 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008268 return NULL;
8269
8270 res = pipe2(fds, flags);
8271 if (res != 0)
8272 return posix_error();
8273 return Py_BuildValue("(ii)", fds[0], fds[1]);
8274}
8275#endif /* HAVE_PIPE2 */
8276
Ross Lagerwall7807c352011-03-17 20:20:30 +02008277#ifdef HAVE_WRITEV
8278PyDoc_STRVAR(posix_writev__doc__,
8279"writev(fd, buffers) -> byteswritten\n\n\
8280Write the contents of buffers to a file descriptor, where buffers is an\n\
8281arbitrary sequence of buffers.\n\
8282Returns the total bytes written.");
8283
8284static PyObject *
8285posix_writev(PyObject *self, PyObject *args)
8286{
8287 int fd, cnt;
8288 Py_ssize_t res;
8289 PyObject *seq;
8290 struct iovec *iov;
8291 Py_buffer *buf;
8292 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8293 return NULL;
8294 if (!PySequence_Check(seq)) {
8295 PyErr_SetString(PyExc_TypeError,
8296 "writev() arg 2 must be a sequence");
8297 return NULL;
8298 }
8299 cnt = PySequence_Size(seq);
8300
8301 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8302 return NULL;
8303 }
8304
8305 Py_BEGIN_ALLOW_THREADS
8306 res = writev(fd, iov, cnt);
8307 Py_END_ALLOW_THREADS
8308
8309 iov_cleanup(iov, buf, cnt);
8310 return PyLong_FromSsize_t(res);
8311}
8312#endif
8313
8314#ifdef HAVE_PWRITE
8315PyDoc_STRVAR(posix_pwrite__doc__,
8316"pwrite(fd, string, offset) -> byteswritten\n\n\
8317Write string to a file descriptor, fd, from offset, leaving the file\n\
8318offset unchanged.");
8319
8320static PyObject *
8321posix_pwrite(PyObject *self, PyObject *args)
8322{
8323 Py_buffer pbuf;
8324 int fd;
8325 off_t offset;
8326 Py_ssize_t size;
8327
8328 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8329 return NULL;
8330
8331 if (!_PyVerify_fd(fd)) {
8332 PyBuffer_Release(&pbuf);
8333 return posix_error();
8334 }
8335 Py_BEGIN_ALLOW_THREADS
8336 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8337 Py_END_ALLOW_THREADS
8338 PyBuffer_Release(&pbuf);
8339 if (size < 0)
8340 return posix_error();
8341 return PyLong_FromSsize_t(size);
8342}
8343#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008344
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008345#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008346PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008347"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8348Create a FIFO (a POSIX named pipe).\n\
8349\n\
8350If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8351 and path should be relative; path will then be relative to that directory.\n\
8352dir_fd may not be implemented on your platform.\n\
8353 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008354
Barry Warsaw53699e91996-12-10 23:23:01 +00008355static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008356posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008357{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008358 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008360 int dir_fd = DEFAULT_DIR_FD;
8361 int result;
8362 PyObject *return_value = NULL;
8363 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8364
8365 memset(&path, 0, sizeof(path));
8366 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8367 path_converter, &path,
8368 &mode,
8369#ifdef HAVE_MKFIFOAT
8370 dir_fd_converter, &dir_fd
8371#else
8372 dir_fd_unavailable, &dir_fd
8373#endif
8374 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008375 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008376
Victor Stinner8c62be82010-05-06 00:08:46 +00008377 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008378#ifdef HAVE_MKFIFOAT
8379 if (dir_fd != DEFAULT_DIR_FD)
8380 result = mkfifoat(dir_fd, path.narrow, mode);
8381 else
8382#endif
8383 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008385
8386 if (result < 0) {
8387 return_value = posix_error();
8388 goto exit;
8389 }
8390
8391 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008393
8394exit:
8395 path_cleanup(&path);
8396 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008397}
8398#endif
8399
Neal Norwitz11690112002-07-30 01:08:28 +00008400#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008401PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008402"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008403Create a filesystem node (file, device special file or named pipe)\n\
8404named filename. mode specifies both the permissions to use and the\n\
8405type of node to be created, being combined (bitwise OR) with one of\n\
8406S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008407device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008408os.makedev()), otherwise it is ignored.\n\
8409\n\
8410If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8411 and path should be relative; path will then be relative to that directory.\n\
8412dir_fd may not be implemented on your platform.\n\
8413 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008414
8415
8416static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008417posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008418{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008419 path_t path;
8420 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008422 int dir_fd = DEFAULT_DIR_FD;
8423 int result;
8424 PyObject *return_value = NULL;
8425 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8426
8427 memset(&path, 0, sizeof(path));
8428 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8429 path_converter, &path,
8430 &mode, &device,
8431#ifdef HAVE_MKNODAT
8432 dir_fd_converter, &dir_fd
8433#else
8434 dir_fd_unavailable, &dir_fd
8435#endif
8436 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008438
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008440#ifdef HAVE_MKNODAT
8441 if (dir_fd != DEFAULT_DIR_FD)
8442 result = mknodat(dir_fd, path.narrow, mode, device);
8443 else
8444#endif
8445 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008446 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008447
8448 if (result < 0) {
8449 return_value = posix_error();
8450 goto exit;
8451 }
8452
8453 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008454 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008455
Larry Hastings9cf065c2012-06-22 16:30:09 -07008456exit:
8457 path_cleanup(&path);
8458 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008459}
8460#endif
8461
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008462#ifdef HAVE_DEVICE_MACROS
8463PyDoc_STRVAR(posix_major__doc__,
8464"major(device) -> major number\n\
8465Extracts a device major number from a raw device number.");
8466
8467static PyObject *
8468posix_major(PyObject *self, PyObject *args)
8469{
Victor Stinner8c62be82010-05-06 00:08:46 +00008470 int device;
8471 if (!PyArg_ParseTuple(args, "i:major", &device))
8472 return NULL;
8473 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008474}
8475
8476PyDoc_STRVAR(posix_minor__doc__,
8477"minor(device) -> minor number\n\
8478Extracts a device minor number from a raw device number.");
8479
8480static PyObject *
8481posix_minor(PyObject *self, PyObject *args)
8482{
Victor Stinner8c62be82010-05-06 00:08:46 +00008483 int device;
8484 if (!PyArg_ParseTuple(args, "i:minor", &device))
8485 return NULL;
8486 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008487}
8488
8489PyDoc_STRVAR(posix_makedev__doc__,
8490"makedev(major, minor) -> device number\n\
8491Composes a raw device number from the major and minor device numbers.");
8492
8493static PyObject *
8494posix_makedev(PyObject *self, PyObject *args)
8495{
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 int major, minor;
8497 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8498 return NULL;
8499 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008500}
8501#endif /* device macros */
8502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008503
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008504#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008505PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008506"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008507Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008508
Barry Warsaw53699e91996-12-10 23:23:01 +00008509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008510posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008511{
Victor Stinner8c62be82010-05-06 00:08:46 +00008512 int fd;
8513 off_t length;
8514 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008515
Ross Lagerwall7807c352011-03-17 20:20:30 +02008516 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008517 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008518
Victor Stinner8c62be82010-05-06 00:08:46 +00008519 Py_BEGIN_ALLOW_THREADS
8520 res = ftruncate(fd, length);
8521 Py_END_ALLOW_THREADS
8522 if (res < 0)
8523 return posix_error();
8524 Py_INCREF(Py_None);
8525 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008526}
8527#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008528
Ross Lagerwall7807c352011-03-17 20:20:30 +02008529#ifdef HAVE_TRUNCATE
8530PyDoc_STRVAR(posix_truncate__doc__,
8531"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008532Truncate the file given by path to length bytes.\n\
8533On some platforms, path may also be specified as an open file descriptor.\n\
8534 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008535
8536static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008537posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008538{
Georg Brandl306336b2012-06-24 12:55:33 +02008539 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008540 off_t length;
8541 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008542 PyObject *result = NULL;
8543 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008544
Georg Brandl306336b2012-06-24 12:55:33 +02008545 memset(&path, 0, sizeof(path));
8546#ifdef HAVE_FTRUNCATE
8547 path.allow_fd = 1;
8548#endif
8549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8550 path_converter, &path,
8551 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008552 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008553
8554 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008555#ifdef HAVE_FTRUNCATE
8556 if (path.fd != -1)
8557 res = ftruncate(path.fd, length);
8558 else
8559#endif
8560 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008561 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008562 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008563 result = path_posix_error("truncate", &path);
8564 else {
8565 Py_INCREF(Py_None);
8566 result = Py_None;
8567 }
8568 path_cleanup(&path);
8569 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008570}
8571#endif
8572
8573#ifdef HAVE_POSIX_FALLOCATE
8574PyDoc_STRVAR(posix_posix_fallocate__doc__,
8575"posix_fallocate(fd, offset, len)\n\n\
8576Ensures that enough disk space is allocated for the file specified by fd\n\
8577starting from offset and continuing for len bytes.");
8578
8579static PyObject *
8580posix_posix_fallocate(PyObject *self, PyObject *args)
8581{
8582 off_t len, offset;
8583 int res, fd;
8584
8585 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8586 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8587 return NULL;
8588
8589 Py_BEGIN_ALLOW_THREADS
8590 res = posix_fallocate(fd, offset, len);
8591 Py_END_ALLOW_THREADS
8592 if (res != 0) {
8593 errno = res;
8594 return posix_error();
8595 }
8596 Py_RETURN_NONE;
8597}
8598#endif
8599
8600#ifdef HAVE_POSIX_FADVISE
8601PyDoc_STRVAR(posix_posix_fadvise__doc__,
8602"posix_fadvise(fd, offset, len, advice)\n\n\
8603Announces an intention to access data in a specific pattern thus allowing\n\
8604the kernel to make optimizations.\n\
8605The advice applies to the region of the file specified by fd starting at\n\
8606offset and continuing for len bytes.\n\
8607advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8608POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8609POSIX_FADV_DONTNEED.");
8610
8611static PyObject *
8612posix_posix_fadvise(PyObject *self, PyObject *args)
8613{
8614 off_t len, offset;
8615 int res, fd, advice;
8616
8617 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8618 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8619 return NULL;
8620
8621 Py_BEGIN_ALLOW_THREADS
8622 res = posix_fadvise(fd, offset, len, advice);
8623 Py_END_ALLOW_THREADS
8624 if (res != 0) {
8625 errno = res;
8626 return posix_error();
8627 }
8628 Py_RETURN_NONE;
8629}
8630#endif
8631
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008632#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008633PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008634"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008635Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008636
Fred Drake762e2061999-08-26 17:23:54 +00008637/* Save putenv() parameters as values here, so we can collect them when they
8638 * get re-set with another call for the same key. */
8639static PyObject *posix_putenv_garbage;
8640
Tim Peters5aa91602002-01-30 05:46:57 +00008641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008642posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008643{
Victor Stinner84ae1182010-05-06 22:05:07 +00008644 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008645#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008646 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008647 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008648
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008650 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008651 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008653
Victor Stinner65170952011-11-22 22:16:17 +01008654 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008655 if (newstr == NULL) {
8656 PyErr_NoMemory();
8657 goto error;
8658 }
Victor Stinner65170952011-11-22 22:16:17 +01008659 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8660 PyErr_Format(PyExc_ValueError,
8661 "the environment variable is longer than %u characters",
8662 _MAX_ENV);
8663 goto error;
8664 }
8665
Victor Stinner8c62be82010-05-06 00:08:46 +00008666 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008667 if (newenv == NULL)
8668 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008669 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008671 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008672 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008673#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008674 PyObject *os1, *os2;
8675 char *s1, *s2;
8676 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008677
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008678 if (!PyArg_ParseTuple(args,
8679 "O&O&:putenv",
8680 PyUnicode_FSConverter, &os1,
8681 PyUnicode_FSConverter, &os2))
8682 return NULL;
8683 s1 = PyBytes_AsString(os1);
8684 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008685
Victor Stinner65170952011-11-22 22:16:17 +01008686 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008687 if (newstr == NULL) {
8688 PyErr_NoMemory();
8689 goto error;
8690 }
8691
Victor Stinner8c62be82010-05-06 00:08:46 +00008692 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008693 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008695 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008696 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008697#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008698
Victor Stinner8c62be82010-05-06 00:08:46 +00008699 /* Install the first arg and newstr in posix_putenv_garbage;
8700 * this will cause previous value to be collected. This has to
8701 * happen after the real putenv() call because the old value
8702 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008703 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008704 /* really not much we can do; just leak */
8705 PyErr_Clear();
8706 }
8707 else {
8708 Py_DECREF(newstr);
8709 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008710
Martin v. Löwis011e8422009-05-05 04:43:17 +00008711#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 Py_DECREF(os1);
8713 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008714#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008715 Py_RETURN_NONE;
8716
8717error:
8718#ifndef MS_WINDOWS
8719 Py_DECREF(os1);
8720 Py_DECREF(os2);
8721#endif
8722 Py_XDECREF(newstr);
8723 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008724}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008725#endif /* putenv */
8726
Guido van Rossumc524d952001-10-19 01:31:59 +00008727#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008728PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008729"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008730Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008731
8732static PyObject *
8733posix_unsetenv(PyObject *self, PyObject *args)
8734{
Victor Stinner65170952011-11-22 22:16:17 +01008735 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008736#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008737 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008738#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008739
8740 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008741
Victor Stinner65170952011-11-22 22:16:17 +01008742 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008743 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008744
Victor Stinner984890f2011-11-24 13:53:38 +01008745#ifdef HAVE_BROKEN_UNSETENV
8746 unsetenv(PyBytes_AS_STRING(name));
8747#else
Victor Stinner65170952011-11-22 22:16:17 +01008748 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008749 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008750 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008751 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008752 }
Victor Stinner984890f2011-11-24 13:53:38 +01008753#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008754
Victor Stinner8c62be82010-05-06 00:08:46 +00008755 /* Remove the key from posix_putenv_garbage;
8756 * this will cause it to be collected. This has to
8757 * happen after the real unsetenv() call because the
8758 * old value was still accessible until then.
8759 */
Victor Stinner65170952011-11-22 22:16:17 +01008760 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 /* really not much we can do; just leak */
8762 PyErr_Clear();
8763 }
Victor Stinner65170952011-11-22 22:16:17 +01008764 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008765 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008766}
8767#endif /* unsetenv */
8768
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008769PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008770"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008771Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008772
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008774posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008775{
Victor Stinner8c62be82010-05-06 00:08:46 +00008776 int code;
8777 char *message;
8778 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8779 return NULL;
8780 message = strerror(code);
8781 if (message == NULL) {
8782 PyErr_SetString(PyExc_ValueError,
8783 "strerror() argument out of range");
8784 return NULL;
8785 }
Victor Stinner1b579672011-12-17 05:47:23 +01008786 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008787}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008788
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008789
Guido van Rossumc9641791998-08-04 15:26:23 +00008790#ifdef HAVE_SYS_WAIT_H
8791
Fred Drake106c1a02002-04-23 15:58:02 +00008792#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008793PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008794"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008795Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008796
8797static PyObject *
8798posix_WCOREDUMP(PyObject *self, PyObject *args)
8799{
Victor Stinner8c62be82010-05-06 00:08:46 +00008800 WAIT_TYPE status;
8801 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008802
Victor Stinner8c62be82010-05-06 00:08:46 +00008803 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8804 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008805
Victor Stinner8c62be82010-05-06 00:08:46 +00008806 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008807}
8808#endif /* WCOREDUMP */
8809
8810#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008811PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008812"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008813Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008814job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008815
8816static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008817posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008818{
Victor Stinner8c62be82010-05-06 00:08:46 +00008819 WAIT_TYPE status;
8820 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008821
Victor Stinner8c62be82010-05-06 00:08:46 +00008822 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8823 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008824
Victor Stinner8c62be82010-05-06 00:08:46 +00008825 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008826}
8827#endif /* WIFCONTINUED */
8828
Guido van Rossumc9641791998-08-04 15:26:23 +00008829#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008830PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008831"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008832Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008833
8834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008835posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008836{
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 WAIT_TYPE status;
8838 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008839
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8841 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008842
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008844}
8845#endif /* WIFSTOPPED */
8846
8847#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008848PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008849"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008850Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008851
8852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008853posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008854{
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 WAIT_TYPE status;
8856 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008857
Victor Stinner8c62be82010-05-06 00:08:46 +00008858 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8859 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008860
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008862}
8863#endif /* WIFSIGNALED */
8864
8865#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008866PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008867"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008868Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008869system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008870
8871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008872posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008873{
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 WAIT_TYPE status;
8875 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008876
Victor Stinner8c62be82010-05-06 00:08:46 +00008877 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8878 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008879
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008881}
8882#endif /* WIFEXITED */
8883
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008884#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008885PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008886"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008887Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008888
8889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008890posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008891{
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 WAIT_TYPE status;
8893 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008894
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8896 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008897
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008899}
8900#endif /* WEXITSTATUS */
8901
8902#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008903PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008904"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008905Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008906value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008907
8908static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008909posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008910{
Victor Stinner8c62be82010-05-06 00:08:46 +00008911 WAIT_TYPE status;
8912 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008913
Victor Stinner8c62be82010-05-06 00:08:46 +00008914 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8915 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008916
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008918}
8919#endif /* WTERMSIG */
8920
8921#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008922PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008923"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008924Return the signal that stopped the process that provided\n\
8925the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008926
8927static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008928posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008929{
Victor Stinner8c62be82010-05-06 00:08:46 +00008930 WAIT_TYPE status;
8931 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008932
Victor Stinner8c62be82010-05-06 00:08:46 +00008933 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8934 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008935
Victor Stinner8c62be82010-05-06 00:08:46 +00008936 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008937}
8938#endif /* WSTOPSIG */
8939
8940#endif /* HAVE_SYS_WAIT_H */
8941
8942
Thomas Wouters477c8d52006-05-27 19:21:47 +00008943#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008944#ifdef _SCO_DS
8945/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8946 needed definitions in sys/statvfs.h */
8947#define _SVID3
8948#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008949#include <sys/statvfs.h>
8950
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008951static PyObject*
8952_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008953 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8954 if (v == NULL)
8955 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008956
8957#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8959 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8960 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8961 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8962 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8963 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8964 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8965 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8966 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8967 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008968#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008969 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8970 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8971 PyStructSequence_SET_ITEM(v, 2,
8972 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8973 PyStructSequence_SET_ITEM(v, 3,
8974 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8975 PyStructSequence_SET_ITEM(v, 4,
8976 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8977 PyStructSequence_SET_ITEM(v, 5,
8978 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8979 PyStructSequence_SET_ITEM(v, 6,
8980 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8981 PyStructSequence_SET_ITEM(v, 7,
8982 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8983 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8984 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008985#endif
8986
Victor Stinner8c62be82010-05-06 00:08:46 +00008987 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008988}
8989
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008990PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008991"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008992Perform an fstatvfs system call on the given fd.\n\
8993Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008994
8995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008996posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008997{
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 int fd, res;
8999 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009000
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9002 return NULL;
9003 Py_BEGIN_ALLOW_THREADS
9004 res = fstatvfs(fd, &st);
9005 Py_END_ALLOW_THREADS
9006 if (res != 0)
9007 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009008
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009010}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009011#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009012
9013
Thomas Wouters477c8d52006-05-27 19:21:47 +00009014#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009015#include <sys/statvfs.h>
9016
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009017PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009018"statvfs(path)\n\n\
9019Perform a statvfs system call on the given path.\n\
9020\n\
9021path may always be specified as a string.\n\
9022On some platforms, path may also be specified as an open file descriptor.\n\
9023 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009024
9025static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009026posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009027{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009028 static char *keywords[] = {"path", NULL};
9029 path_t path;
9030 int result;
9031 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009032 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009033
Larry Hastings9cf065c2012-06-22 16:30:09 -07009034 memset(&path, 0, sizeof(path));
9035#ifdef HAVE_FSTATVFS
9036 path.allow_fd = 1;
9037#endif
9038 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9039 path_converter, &path
9040 ))
9041 return NULL;
9042
9043 Py_BEGIN_ALLOW_THREADS
9044#ifdef HAVE_FSTATVFS
9045 if (path.fd != -1) {
9046#ifdef __APPLE__
9047 /* handle weak-linking on Mac OS X 10.3 */
9048 if (fstatvfs == NULL) {
9049 fd_specified("statvfs", path.fd);
9050 goto exit;
9051 }
9052#endif
9053 result = fstatvfs(path.fd, &st);
9054 }
9055 else
9056#endif
9057 result = statvfs(path.narrow, &st);
9058 Py_END_ALLOW_THREADS
9059
9060 if (result) {
9061 return_value = path_posix_error("statvfs", &path);
9062 goto exit;
9063 }
9064
9065 return_value = _pystatvfs_fromstructstatvfs(st);
9066
9067exit:
9068 path_cleanup(&path);
9069 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009070}
9071#endif /* HAVE_STATVFS */
9072
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009073#ifdef MS_WINDOWS
9074PyDoc_STRVAR(win32__getdiskusage__doc__,
9075"_getdiskusage(path) -> (total, free)\n\n\
9076Return disk usage statistics about the given path as (total, free) tuple.");
9077
9078static PyObject *
9079win32__getdiskusage(PyObject *self, PyObject *args)
9080{
9081 BOOL retval;
9082 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009083 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009084
Victor Stinner6139c1b2011-11-09 22:14:14 +01009085 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009086 return NULL;
9087
9088 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009089 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009090 Py_END_ALLOW_THREADS
9091 if (retval == 0)
9092 return PyErr_SetFromWindowsErr(0);
9093
9094 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9095}
9096#endif
9097
9098
Fred Drakec9680921999-12-13 16:37:25 +00009099/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9100 * It maps strings representing configuration variable names to
9101 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009102 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009103 * rarely-used constants. There are three separate tables that use
9104 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009105 *
9106 * This code is always included, even if none of the interfaces that
9107 * need it are included. The #if hackery needed to avoid it would be
9108 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009109 */
9110struct constdef {
9111 char *name;
9112 long value;
9113};
9114
Fred Drake12c6e2d1999-12-14 21:25:03 +00009115static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009116conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009117 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009118{
Christian Heimes217cfd12007-12-02 14:31:20 +00009119 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009120 *valuep = PyLong_AS_LONG(arg);
9121 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009122 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009123 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009124 /* look up the value in the table using a binary search */
9125 size_t lo = 0;
9126 size_t mid;
9127 size_t hi = tablesize;
9128 int cmp;
9129 const char *confname;
9130 if (!PyUnicode_Check(arg)) {
9131 PyErr_SetString(PyExc_TypeError,
9132 "configuration names must be strings or integers");
9133 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009135 confname = _PyUnicode_AsString(arg);
9136 if (confname == NULL)
9137 return 0;
9138 while (lo < hi) {
9139 mid = (lo + hi) / 2;
9140 cmp = strcmp(confname, table[mid].name);
9141 if (cmp < 0)
9142 hi = mid;
9143 else if (cmp > 0)
9144 lo = mid + 1;
9145 else {
9146 *valuep = table[mid].value;
9147 return 1;
9148 }
9149 }
9150 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9151 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009153}
9154
9155
9156#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9157static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009158#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009159 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009160#endif
9161#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009162 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009163#endif
Fred Drakec9680921999-12-13 16:37:25 +00009164#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009165 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009166#endif
9167#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009168 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009169#endif
9170#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009172#endif
9173#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009175#endif
9176#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009178#endif
9179#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009181#endif
9182#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009184#endif
9185#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009187#endif
9188#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009190#endif
9191#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009193#endif
9194#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009196#endif
9197#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009199#endif
9200#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009202#endif
9203#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009205#endif
9206#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009208#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009209#ifdef _PC_ACL_ENABLED
9210 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9211#endif
9212#ifdef _PC_MIN_HOLE_SIZE
9213 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9214#endif
9215#ifdef _PC_ALLOC_SIZE_MIN
9216 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9217#endif
9218#ifdef _PC_REC_INCR_XFER_SIZE
9219 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9220#endif
9221#ifdef _PC_REC_MAX_XFER_SIZE
9222 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9223#endif
9224#ifdef _PC_REC_MIN_XFER_SIZE
9225 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9226#endif
9227#ifdef _PC_REC_XFER_ALIGN
9228 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9229#endif
9230#ifdef _PC_SYMLINK_MAX
9231 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9232#endif
9233#ifdef _PC_XATTR_ENABLED
9234 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9235#endif
9236#ifdef _PC_XATTR_EXISTS
9237 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9238#endif
9239#ifdef _PC_TIMESTAMP_RESOLUTION
9240 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9241#endif
Fred Drakec9680921999-12-13 16:37:25 +00009242};
9243
Fred Drakec9680921999-12-13 16:37:25 +00009244static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009245conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009246{
9247 return conv_confname(arg, valuep, posix_constants_pathconf,
9248 sizeof(posix_constants_pathconf)
9249 / sizeof(struct constdef));
9250}
9251#endif
9252
9253#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009254PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009255"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009256Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009257If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009258
9259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009260posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009261{
9262 PyObject *result = NULL;
9263 int name, fd;
9264
Fred Drake12c6e2d1999-12-14 21:25:03 +00009265 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9266 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009267 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009268
Stefan Krah0e803b32010-11-26 16:16:47 +00009269 errno = 0;
9270 limit = fpathconf(fd, name);
9271 if (limit == -1 && errno != 0)
9272 posix_error();
9273 else
9274 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009275 }
9276 return result;
9277}
9278#endif
9279
9280
9281#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009282PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009283"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009284Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009285If there is no limit, return -1.\n\
9286On some platforms, path may also be specified as an open file descriptor.\n\
9287 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009288
9289static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009290posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009291{
Georg Brandl306336b2012-06-24 12:55:33 +02009292 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009293 PyObject *result = NULL;
9294 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009295 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009296
Georg Brandl306336b2012-06-24 12:55:33 +02009297 memset(&path, 0, sizeof(path));
9298#ifdef HAVE_FPATHCONF
9299 path.allow_fd = 1;
9300#endif
9301 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9302 path_converter, &path,
9303 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009304 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009305
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009307#ifdef HAVE_FPATHCONF
9308 if (path.fd != -1)
9309 limit = fpathconf(path.fd, name);
9310 else
9311#endif
9312 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 if (limit == -1 && errno != 0) {
9314 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009315 /* could be a path or name problem */
9316 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009317 else
Georg Brandl306336b2012-06-24 12:55:33 +02009318 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 }
9320 else
9321 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009322 }
Georg Brandl306336b2012-06-24 12:55:33 +02009323 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009324 return result;
9325}
9326#endif
9327
9328#ifdef HAVE_CONFSTR
9329static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009330#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009332#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009333#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009335#endif
9336#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009338#endif
Fred Draked86ed291999-12-15 15:34:33 +00009339#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009341#endif
9342#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009344#endif
9345#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009347#endif
9348#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009350#endif
Fred Drakec9680921999-12-13 16:37:25 +00009351#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009353#endif
9354#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009356#endif
9357#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009359#endif
9360#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009362#endif
9363#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
9369#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
Fred Draked86ed291999-12-15 15:34:33 +00009375#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009377#endif
Fred Drakec9680921999-12-13 16:37:25 +00009378#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
Fred Draked86ed291999-12-15 15:34:33 +00009381#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009383#endif
9384#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009386#endif
9387#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009389#endif
9390#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009392#endif
Fred Drakec9680921999-12-13 16:37:25 +00009393#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009395#endif
9396#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
9399#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009401#endif
9402#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009404#endif
9405#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009407#endif
9408#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009410#endif
9411#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009413#endif
9414#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009416#endif
9417#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009419#endif
9420#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009422#endif
9423#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009425#endif
9426#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009428#endif
9429#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009431#endif
9432#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009434#endif
9435#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009437#endif
9438#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009440#endif
Fred Draked86ed291999-12-15 15:34:33 +00009441#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009443#endif
9444#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009446#endif
9447#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009449#endif
9450#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009452#endif
9453#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009455#endif
9456#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009458#endif
9459#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009461#endif
9462#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009464#endif
9465#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009467#endif
9468#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009470#endif
9471#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009473#endif
9474#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009476#endif
9477#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009479#endif
Fred Drakec9680921999-12-13 16:37:25 +00009480};
9481
9482static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009483conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009484{
9485 return conv_confname(arg, valuep, posix_constants_confstr,
9486 sizeof(posix_constants_confstr)
9487 / sizeof(struct constdef));
9488}
9489
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009490PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009491"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009492Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009493
9494static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009495posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009496{
9497 PyObject *result = NULL;
9498 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009499 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009500 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009501
Victor Stinnercb043522010-09-10 23:49:04 +00009502 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9503 return NULL;
9504
9505 errno = 0;
9506 len = confstr(name, buffer, sizeof(buffer));
9507 if (len == 0) {
9508 if (errno) {
9509 posix_error();
9510 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009511 }
9512 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009513 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009514 }
9515 }
Victor Stinnercb043522010-09-10 23:49:04 +00009516
9517 if ((unsigned int)len >= sizeof(buffer)) {
9518 char *buf = PyMem_Malloc(len);
9519 if (buf == NULL)
9520 return PyErr_NoMemory();
9521 confstr(name, buf, len);
9522 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9523 PyMem_Free(buf);
9524 }
9525 else
9526 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009527 return result;
9528}
9529#endif
9530
9531
9532#ifdef HAVE_SYSCONF
9533static struct constdef posix_constants_sysconf[] = {
9534#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009536#endif
9537#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
Fred Draked86ed291999-12-15 15:34:33 +00009564#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009566#endif
9567#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009569#endif
Fred Drakec9680921999-12-13 16:37:25 +00009570#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
Fred Drakec9680921999-12-13 16:37:25 +00009573#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
9585#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
Fred Draked86ed291999-12-15 15:34:33 +00009588#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009590#endif
Fred Drakec9680921999-12-13 16:37:25 +00009591#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
Fred Draked86ed291999-12-15 15:34:33 +00009606#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009608#endif
Fred Drakec9680921999-12-13 16:37:25 +00009609#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
9639#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
9648#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
9654#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
9657#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
9666#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009668#endif
9669#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009671#endif
9672#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009674#endif
9675#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009677#endif
Fred Draked86ed291999-12-15 15:34:33 +00009678#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009680#endif
Fred Drakec9680921999-12-13 16:37:25 +00009681#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009683#endif
9684#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009686#endif
9687#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009689#endif
Fred Draked86ed291999-12-15 15:34:33 +00009690#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009692#endif
Fred Drakec9680921999-12-13 16:37:25 +00009693#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
Fred Draked86ed291999-12-15 15:34:33 +00009696#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009698#endif
9699#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009701#endif
Fred Drakec9680921999-12-13 16:37:25 +00009702#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009704#endif
9705#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
9708#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009710#endif
9711#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
Fred Draked86ed291999-12-15 15:34:33 +00009714#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009716#endif
Fred Drakec9680921999-12-13 16:37:25 +00009717#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
Fred Draked86ed291999-12-15 15:34:33 +00009738#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009740#endif
Fred Drakec9680921999-12-13 16:37:25 +00009741#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
Fred Draked86ed291999-12-15 15:34:33 +00009747#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009749#endif
Fred Drakec9680921999-12-13 16:37:25 +00009750#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
9759#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
Fred Draked86ed291999-12-15 15:34:33 +00009777#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009779#endif
9780#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009782#endif
Fred Drakec9680921999-12-13 16:37:25 +00009783#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
Fred Draked86ed291999-12-15 15:34:33 +00009888#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009890#endif
Fred Drakec9680921999-12-13 16:37:25 +00009891#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026};
10027
10028static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010029conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010030{
10031 return conv_confname(arg, valuep, posix_constants_sysconf,
10032 sizeof(posix_constants_sysconf)
10033 / sizeof(struct constdef));
10034}
10035
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010036PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010037"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010038Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010039
10040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010041posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010042{
10043 PyObject *result = NULL;
10044 int name;
10045
10046 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10047 int value;
10048
10049 errno = 0;
10050 value = sysconf(name);
10051 if (value == -1 && errno != 0)
10052 posix_error();
10053 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010054 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010055 }
10056 return result;
10057}
10058#endif
10059
10060
Fred Drakebec628d1999-12-15 18:31:10 +000010061/* This code is used to ensure that the tables of configuration value names
10062 * are in sorted order as required by conv_confname(), and also to build the
10063 * the exported dictionaries that are used to publish information about the
10064 * names available on the host platform.
10065 *
10066 * Sorting the table at runtime ensures that the table is properly ordered
10067 * when used, even for platforms we're not able to test on. It also makes
10068 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010069 */
Fred Drakebec628d1999-12-15 18:31:10 +000010070
10071static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010072cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010073{
10074 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010076 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010078
10079 return strcmp(c1->name, c2->name);
10080}
10081
10082static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010083setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010085{
Fred Drakebec628d1999-12-15 18:31:10 +000010086 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010087 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010088
10089 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10090 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010091 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010093
Barry Warsaw3155db32000-04-13 15:20:40 +000010094 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 PyObject *o = PyLong_FromLong(table[i].value);
10096 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10097 Py_XDECREF(o);
10098 Py_DECREF(d);
10099 return -1;
10100 }
10101 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010102 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010103 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010104}
10105
Fred Drakebec628d1999-12-15 18:31:10 +000010106/* Return -1 on failure, 0 on success. */
10107static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010108setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010109{
10110#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010111 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010112 sizeof(posix_constants_pathconf)
10113 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010114 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010115 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010116#endif
10117#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010118 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010119 sizeof(posix_constants_confstr)
10120 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010121 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010122 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010123#endif
10124#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010125 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010126 sizeof(posix_constants_sysconf)
10127 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010128 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010129 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010130#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010131 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010132}
Fred Draked86ed291999-12-15 15:34:33 +000010133
10134
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010135PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010136"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010137Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010138in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010139
10140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010141posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010142{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010143 abort();
10144 /*NOTREACHED*/
10145 Py_FatalError("abort() called from Python code didn't abort!");
10146 return NULL;
10147}
Fred Drakebec628d1999-12-15 18:31:10 +000010148
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010149#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010150PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010151"startfile(filepath [, operation]) - Start a file with its associated\n\
10152application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010153\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010154When \"operation\" is not specified or \"open\", this acts like\n\
10155double-clicking the file in Explorer, or giving the file name as an\n\
10156argument to the DOS \"start\" command: the file is opened with whatever\n\
10157application (if any) its extension is associated.\n\
10158When another \"operation\" is given, it specifies what should be done with\n\
10159the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010160\n\
10161startfile returns as soon as the associated application is launched.\n\
10162There is no option to wait for the application to close, and no way\n\
10163to retrieve the application's exit status.\n\
10164\n\
10165The filepath is relative to the current directory. If you want to use\n\
10166an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010167the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010168
10169static PyObject *
10170win32_startfile(PyObject *self, PyObject *args)
10171{
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 PyObject *ofilepath;
10173 char *filepath;
10174 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010175 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010177
Victor Stinnereb5657a2011-09-30 01:44:27 +020010178 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 if (!PyArg_ParseTuple(args, "U|s:startfile",
10180 &unipath, &operation)) {
10181 PyErr_Clear();
10182 goto normal;
10183 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010184
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010186 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010188 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 PyErr_Clear();
10190 operation = NULL;
10191 goto normal;
10192 }
10193 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010194
Victor Stinnereb5657a2011-09-30 01:44:27 +020010195 wpath = PyUnicode_AsUnicode(unipath);
10196 if (wpath == NULL)
10197 goto normal;
10198 if (uoperation) {
10199 woperation = PyUnicode_AsUnicode(uoperation);
10200 if (woperation == NULL)
10201 goto normal;
10202 }
10203 else
10204 woperation = NULL;
10205
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010207 rc = ShellExecuteW((HWND)0, woperation, wpath,
10208 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 Py_END_ALLOW_THREADS
10210
Victor Stinnereb5657a2011-09-30 01:44:27 +020010211 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010213 win32_error_object("startfile", unipath);
10214 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 }
10216 Py_INCREF(Py_None);
10217 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010218
10219normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10221 PyUnicode_FSConverter, &ofilepath,
10222 &operation))
10223 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010224 if (win32_warn_bytes_api()) {
10225 Py_DECREF(ofilepath);
10226 return NULL;
10227 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 filepath = PyBytes_AsString(ofilepath);
10229 Py_BEGIN_ALLOW_THREADS
10230 rc = ShellExecute((HWND)0, operation, filepath,
10231 NULL, NULL, SW_SHOWNORMAL);
10232 Py_END_ALLOW_THREADS
10233 if (rc <= (HINSTANCE)32) {
10234 PyObject *errval = win32_error("startfile", filepath);
10235 Py_DECREF(ofilepath);
10236 return errval;
10237 }
10238 Py_DECREF(ofilepath);
10239 Py_INCREF(Py_None);
10240 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010241}
10242#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010243
Martin v. Löwis438b5342002-12-27 10:16:42 +000010244#ifdef HAVE_GETLOADAVG
10245PyDoc_STRVAR(posix_getloadavg__doc__,
10246"getloadavg() -> (float, float, float)\n\n\
10247Return the number of processes in the system run queue averaged over\n\
10248the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10249was unobtainable");
10250
10251static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010252posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010253{
10254 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010255 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010256 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10257 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010258 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010259 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010260}
10261#endif
10262
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010263PyDoc_STRVAR(device_encoding__doc__,
10264"device_encoding(fd) -> str\n\n\
10265Return a string describing the encoding of the device\n\
10266if the output is a terminal; else return None.");
10267
10268static PyObject *
10269device_encoding(PyObject *self, PyObject *args)
10270{
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010272
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10274 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010275
10276 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010277}
10278
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010279#ifdef HAVE_SETRESUID
10280PyDoc_STRVAR(posix_setresuid__doc__,
10281"setresuid(ruid, euid, suid)\n\n\
10282Set the current process's real, effective, and saved user ids.");
10283
10284static PyObject*
10285posix_setresuid (PyObject *self, PyObject *args)
10286{
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010288 uid_t ruid, euid, suid;
10289 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10290 _Py_Uid_Converter, &ruid,
10291 _Py_Uid_Converter, &euid,
10292 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 return NULL;
10294 if (setresuid(ruid, euid, suid) < 0)
10295 return posix_error();
10296 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010297}
10298#endif
10299
10300#ifdef HAVE_SETRESGID
10301PyDoc_STRVAR(posix_setresgid__doc__,
10302"setresgid(rgid, egid, sgid)\n\n\
10303Set the current process's real, effective, and saved group ids.");
10304
10305static PyObject*
10306posix_setresgid (PyObject *self, PyObject *args)
10307{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010308 gid_t rgid, egid, sgid;
10309 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10310 _Py_Gid_Converter, &rgid,
10311 _Py_Gid_Converter, &egid,
10312 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 return NULL;
10314 if (setresgid(rgid, egid, sgid) < 0)
10315 return posix_error();
10316 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010317}
10318#endif
10319
10320#ifdef HAVE_GETRESUID
10321PyDoc_STRVAR(posix_getresuid__doc__,
10322"getresuid() -> (ruid, euid, suid)\n\n\
10323Get tuple of the current process's real, effective, and saved user ids.");
10324
10325static PyObject*
10326posix_getresuid (PyObject *self, PyObject *noargs)
10327{
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 if (getresuid(&ruid, &euid, &suid) < 0)
10330 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010331 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10332 _PyLong_FromUid(euid),
10333 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010334}
10335#endif
10336
10337#ifdef HAVE_GETRESGID
10338PyDoc_STRVAR(posix_getresgid__doc__,
10339"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010340Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010341
10342static PyObject*
10343posix_getresgid (PyObject *self, PyObject *noargs)
10344{
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 if (getresgid(&rgid, &egid, &sgid) < 0)
10347 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010348 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10349 _PyLong_FromGid(egid),
10350 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010351}
10352#endif
10353
Benjamin Peterson9428d532011-09-14 11:45:52 -040010354#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010355
Benjamin Peterson799bd802011-08-31 22:15:17 -040010356PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010357"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10358Return the value of extended attribute attribute on path.\n\
10359\n\
10360path may be either a string or an open file descriptor.\n\
10361If follow_symlinks is False, and the last element of the path is a symbolic\n\
10362 link, getxattr will examine the symbolic link itself instead of the file\n\
10363 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010364
10365static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010366posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010367{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010368 path_t path;
10369 path_t attribute;
10370 int follow_symlinks = 1;
10371 PyObject *buffer = NULL;
10372 int i;
10373 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010374
Larry Hastings9cf065c2012-06-22 16:30:09 -070010375 memset(&path, 0, sizeof(path));
10376 memset(&attribute, 0, sizeof(attribute));
10377 path.allow_fd = 1;
10378 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10379 path_converter, &path,
10380 path_converter, &attribute,
10381 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010382 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010383
Larry Hastings9cf065c2012-06-22 16:30:09 -070010384 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10385 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010386
Larry Hastings9cf065c2012-06-22 16:30:09 -070010387 for (i = 0; ; i++) {
10388 void *ptr;
10389 ssize_t result;
10390 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10391 Py_ssize_t buffer_size = buffer_sizes[i];
10392 if (!buffer_size) {
10393 path_error("getxattr", &path);
10394 goto exit;
10395 }
10396 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10397 if (!buffer)
10398 goto exit;
10399 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010400
Larry Hastings9cf065c2012-06-22 16:30:09 -070010401 Py_BEGIN_ALLOW_THREADS;
10402 if (path.fd >= 0)
10403 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10404 else if (follow_symlinks)
10405 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10406 else
10407 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10408 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010409
Larry Hastings9cf065c2012-06-22 16:30:09 -070010410 if (result < 0) {
10411 Py_DECREF(buffer);
10412 buffer = NULL;
10413 if (errno == ERANGE)
10414 continue;
10415 path_error("getxattr", &path);
10416 goto exit;
10417 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010418
Larry Hastings9cf065c2012-06-22 16:30:09 -070010419 if (result != buffer_size) {
10420 /* Can only shrink. */
10421 _PyBytes_Resize(&buffer, result);
10422 }
10423 break;
10424 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010425
Larry Hastings9cf065c2012-06-22 16:30:09 -070010426exit:
10427 path_cleanup(&path);
10428 path_cleanup(&attribute);
10429 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010430}
10431
10432PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010433"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10434Set extended attribute attribute on path to value.\n\
10435path may be either a string or an open file descriptor.\n\
10436If follow_symlinks is False, and the last element of the path is a symbolic\n\
10437 link, setxattr will modify the symbolic link itself instead of the file\n\
10438 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010439
10440static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010441posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010442{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010443 path_t path;
10444 path_t attribute;
10445 Py_buffer value;
10446 int flags = 0;
10447 int follow_symlinks = 1;
10448 int result;
10449 PyObject *return_value = NULL;
10450 static char *keywords[] = {"path", "attribute", "value",
10451 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010452
Larry Hastings9cf065c2012-06-22 16:30:09 -070010453 memset(&path, 0, sizeof(path));
10454 path.allow_fd = 1;
10455 memset(&attribute, 0, sizeof(attribute));
10456 memset(&value, 0, sizeof(value));
10457 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10458 keywords,
10459 path_converter, &path,
10460 path_converter, &attribute,
10461 &value, &flags,
10462 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010463 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010464
10465 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10466 goto exit;
10467
Benjamin Peterson799bd802011-08-31 22:15:17 -040010468 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010469 if (path.fd > -1)
10470 result = fsetxattr(path.fd, attribute.narrow,
10471 value.buf, value.len, flags);
10472 else if (follow_symlinks)
10473 result = setxattr(path.narrow, attribute.narrow,
10474 value.buf, value.len, flags);
10475 else
10476 result = lsetxattr(path.narrow, attribute.narrow,
10477 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010478 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010479
Larry Hastings9cf065c2012-06-22 16:30:09 -070010480 if (result) {
10481 return_value = path_error("setxattr", &path);
10482 goto exit;
10483 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010484
Larry Hastings9cf065c2012-06-22 16:30:09 -070010485 return_value = Py_None;
10486 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010487
Larry Hastings9cf065c2012-06-22 16:30:09 -070010488exit:
10489 path_cleanup(&path);
10490 path_cleanup(&attribute);
10491 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010492
Larry Hastings9cf065c2012-06-22 16:30:09 -070010493 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010494}
10495
10496PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010497"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10498Remove extended attribute attribute on path.\n\
10499path may be either a string or an open file descriptor.\n\
10500If follow_symlinks is False, and the last element of the path is a symbolic\n\
10501 link, removexattr will modify the symbolic link itself instead of the file\n\
10502 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010503
10504static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010505posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010506{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010507 path_t path;
10508 path_t attribute;
10509 int follow_symlinks = 1;
10510 int result;
10511 PyObject *return_value = NULL;
10512 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010513
Larry Hastings9cf065c2012-06-22 16:30:09 -070010514 memset(&path, 0, sizeof(path));
10515 memset(&attribute, 0, sizeof(attribute));
10516 path.allow_fd = 1;
10517 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10518 keywords,
10519 path_converter, &path,
10520 path_converter, &attribute,
10521 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010522 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010523
10524 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10525 goto exit;
10526
Benjamin Peterson799bd802011-08-31 22:15:17 -040010527 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010528 if (path.fd > -1)
10529 result = fremovexattr(path.fd, attribute.narrow);
10530 else if (follow_symlinks)
10531 result = removexattr(path.narrow, attribute.narrow);
10532 else
10533 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010534 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010535
Larry Hastings9cf065c2012-06-22 16:30:09 -070010536 if (result) {
10537 return_value = path_error("removexattr", &path);
10538 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010539 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010540
Larry Hastings9cf065c2012-06-22 16:30:09 -070010541 return_value = Py_None;
10542 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010543
Larry Hastings9cf065c2012-06-22 16:30:09 -070010544exit:
10545 path_cleanup(&path);
10546 path_cleanup(&attribute);
10547
10548 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010549}
10550
10551PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010552"listxattr(path='.', *, follow_symlinks=True)\n\n\
10553Return a list of extended attributes on path.\n\
10554\n\
10555path may be either None, a string, or an open file descriptor.\n\
10556if path is None, listxattr will examine the current directory.\n\
10557If follow_symlinks is False, and the last element of the path is a symbolic\n\
10558 link, listxattr will examine the symbolic link itself instead of the file\n\
10559 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010560
10561static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010562posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010563{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010564 path_t path;
10565 int follow_symlinks = 1;
10566 Py_ssize_t i;
10567 PyObject *result = NULL;
10568 char *buffer = NULL;
10569 char *name;
10570 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010571
Larry Hastings9cf065c2012-06-22 16:30:09 -070010572 memset(&path, 0, sizeof(path));
10573 path.allow_fd = 1;
10574 path.fd = -1;
10575 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10576 path_converter, &path,
10577 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010578 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010579
Larry Hastings9cf065c2012-06-22 16:30:09 -070010580 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10581 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010582
Larry Hastings9cf065c2012-06-22 16:30:09 -070010583 name = path.narrow ? path.narrow : ".";
10584 for (i = 0; ; i++) {
10585 char *start, *trace, *end;
10586 ssize_t length;
10587 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10588 Py_ssize_t buffer_size = buffer_sizes[i];
10589 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010590 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010591 path_error("listxattr", &path);
10592 break;
10593 }
10594 buffer = PyMem_MALLOC(buffer_size);
10595 if (!buffer) {
10596 PyErr_NoMemory();
10597 break;
10598 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010599
Larry Hastings9cf065c2012-06-22 16:30:09 -070010600 Py_BEGIN_ALLOW_THREADS;
10601 if (path.fd > -1)
10602 length = flistxattr(path.fd, buffer, buffer_size);
10603 else if (follow_symlinks)
10604 length = listxattr(name, buffer, buffer_size);
10605 else
10606 length = llistxattr(name, buffer, buffer_size);
10607 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010608
Larry Hastings9cf065c2012-06-22 16:30:09 -070010609 if (length < 0) {
10610 if (errno == ERANGE)
10611 continue;
10612 path_error("listxattr", &path);
10613 break;
10614 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010615
Larry Hastings9cf065c2012-06-22 16:30:09 -070010616 result = PyList_New(0);
10617 if (!result) {
10618 goto exit;
10619 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010620
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621 end = buffer + length;
10622 for (trace = start = buffer; trace != end; trace++) {
10623 if (!*trace) {
10624 int error;
10625 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10626 trace - start);
10627 if (!attribute) {
10628 Py_DECREF(result);
10629 result = NULL;
10630 goto exit;
10631 }
10632 error = PyList_Append(result, attribute);
10633 Py_DECREF(attribute);
10634 if (error) {
10635 Py_DECREF(result);
10636 result = NULL;
10637 goto exit;
10638 }
10639 start = trace + 1;
10640 }
10641 }
10642 break;
10643 }
10644exit:
10645 path_cleanup(&path);
10646 if (buffer)
10647 PyMem_FREE(buffer);
10648 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010649}
10650
Benjamin Peterson9428d532011-09-14 11:45:52 -040010651#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010652
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010653
Georg Brandl2fb477c2012-02-21 00:33:36 +010010654PyDoc_STRVAR(posix_urandom__doc__,
10655"urandom(n) -> str\n\n\
10656Return n random bytes suitable for cryptographic use.");
10657
10658static PyObject *
10659posix_urandom(PyObject *self, PyObject *args)
10660{
10661 Py_ssize_t size;
10662 PyObject *result;
10663 int ret;
10664
10665 /* Read arguments */
10666 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10667 return NULL;
10668 if (size < 0)
10669 return PyErr_Format(PyExc_ValueError,
10670 "negative argument not allowed");
10671 result = PyBytes_FromStringAndSize(NULL, size);
10672 if (result == NULL)
10673 return NULL;
10674
10675 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10676 PyBytes_GET_SIZE(result));
10677 if (ret == -1) {
10678 Py_DECREF(result);
10679 return NULL;
10680 }
10681 return result;
10682}
10683
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010684/* Terminal size querying */
10685
10686static PyTypeObject TerminalSizeType;
10687
10688PyDoc_STRVAR(TerminalSize_docstring,
10689 "A tuple of (columns, lines) for holding terminal window size");
10690
10691static PyStructSequence_Field TerminalSize_fields[] = {
10692 {"columns", "width of the terminal window in characters"},
10693 {"lines", "height of the terminal window in characters"},
10694 {NULL, NULL}
10695};
10696
10697static PyStructSequence_Desc TerminalSize_desc = {
10698 "os.terminal_size",
10699 TerminalSize_docstring,
10700 TerminalSize_fields,
10701 2,
10702};
10703
10704#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10705PyDoc_STRVAR(termsize__doc__,
10706 "Return the size of the terminal window as (columns, lines).\n" \
10707 "\n" \
10708 "The optional argument fd (default standard output) specifies\n" \
10709 "which file descriptor should be queried.\n" \
10710 "\n" \
10711 "If the file descriptor is not connected to a terminal, an OSError\n" \
10712 "is thrown.\n" \
10713 "\n" \
10714 "This function will only be defined if an implementation is\n" \
10715 "available for this system.\n" \
10716 "\n" \
10717 "shutil.get_terminal_size is the high-level function which should \n" \
10718 "normally be used, os.get_terminal_size is the low-level implementation.");
10719
10720static PyObject*
10721get_terminal_size(PyObject *self, PyObject *args)
10722{
10723 int columns, lines;
10724 PyObject *termsize;
10725
10726 int fd = fileno(stdout);
10727 /* Under some conditions stdout may not be connected and
10728 * fileno(stdout) may point to an invalid file descriptor. For example
10729 * GUI apps don't have valid standard streams by default.
10730 *
10731 * If this happens, and the optional fd argument is not present,
10732 * the ioctl below will fail returning EBADF. This is what we want.
10733 */
10734
10735 if (!PyArg_ParseTuple(args, "|i", &fd))
10736 return NULL;
10737
10738#ifdef TERMSIZE_USE_IOCTL
10739 {
10740 struct winsize w;
10741 if (ioctl(fd, TIOCGWINSZ, &w))
10742 return PyErr_SetFromErrno(PyExc_OSError);
10743 columns = w.ws_col;
10744 lines = w.ws_row;
10745 }
10746#endif /* TERMSIZE_USE_IOCTL */
10747
10748#ifdef TERMSIZE_USE_CONIO
10749 {
10750 DWORD nhandle;
10751 HANDLE handle;
10752 CONSOLE_SCREEN_BUFFER_INFO csbi;
10753 switch (fd) {
10754 case 0: nhandle = STD_INPUT_HANDLE;
10755 break;
10756 case 1: nhandle = STD_OUTPUT_HANDLE;
10757 break;
10758 case 2: nhandle = STD_ERROR_HANDLE;
10759 break;
10760 default:
10761 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10762 }
10763 handle = GetStdHandle(nhandle);
10764 if (handle == NULL)
10765 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10766 if (handle == INVALID_HANDLE_VALUE)
10767 return PyErr_SetFromWindowsErr(0);
10768
10769 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10770 return PyErr_SetFromWindowsErr(0);
10771
10772 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10773 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10774 }
10775#endif /* TERMSIZE_USE_CONIO */
10776
10777 termsize = PyStructSequence_New(&TerminalSizeType);
10778 if (termsize == NULL)
10779 return NULL;
10780 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10781 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10782 if (PyErr_Occurred()) {
10783 Py_DECREF(termsize);
10784 return NULL;
10785 }
10786 return termsize;
10787}
10788#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10789
10790
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010791static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010792 {"access", (PyCFunction)posix_access,
10793 METH_VARARGS | METH_KEYWORDS,
10794 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010795#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010797#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010798 {"chdir", (PyCFunction)posix_chdir,
10799 METH_VARARGS | METH_KEYWORDS,
10800 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010801#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010802 {"chflags", (PyCFunction)posix_chflags,
10803 METH_VARARGS | METH_KEYWORDS,
10804 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010805#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010806 {"chmod", (PyCFunction)posix_chmod,
10807 METH_VARARGS | METH_KEYWORDS,
10808 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010809#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010810 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010811#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010812#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010813 {"chown", (PyCFunction)posix_chown,
10814 METH_VARARGS | METH_KEYWORDS,
10815 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010816#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010817#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010819#endif /* HAVE_LCHMOD */
10820#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010822#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010823#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010825#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010826#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010828#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010829#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010831#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010832#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010834#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010835#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10837 METH_NOARGS, posix_getcwd__doc__},
10838 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10839 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010840#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010841#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10842 {"link", (PyCFunction)posix_link,
10843 METH_VARARGS | METH_KEYWORDS,
10844 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010845#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010846 {"listdir", (PyCFunction)posix_listdir,
10847 METH_VARARGS | METH_KEYWORDS,
10848 posix_listdir__doc__},
10849 {"lstat", (PyCFunction)posix_lstat,
10850 METH_VARARGS | METH_KEYWORDS,
10851 posix_lstat__doc__},
10852 {"mkdir", (PyCFunction)posix_mkdir,
10853 METH_VARARGS | METH_KEYWORDS,
10854 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010855#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010857#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010858#ifdef HAVE_GETPRIORITY
10859 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10860#endif /* HAVE_GETPRIORITY */
10861#ifdef HAVE_SETPRIORITY
10862 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10863#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010864#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010865 {"readlink", (PyCFunction)posix_readlink,
10866 METH_VARARGS | METH_KEYWORDS,
10867 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010868#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010869#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010870 {"readlink", (PyCFunction)win_readlink,
10871 METH_VARARGS | METH_KEYWORDS,
10872 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010873#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010874 {"rename", (PyCFunction)posix_rename,
10875 METH_VARARGS | METH_KEYWORDS,
10876 posix_rename__doc__},
10877 {"replace", (PyCFunction)posix_replace,
10878 METH_VARARGS | METH_KEYWORDS,
10879 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010880 {"rmdir", (PyCFunction)posix_rmdir,
10881 METH_VARARGS | METH_KEYWORDS,
10882 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010883 {"stat", (PyCFunction)posix_stat,
10884 METH_VARARGS | METH_KEYWORDS,
10885 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010886 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010887#if defined(HAVE_SYMLINK)
10888 {"symlink", (PyCFunction)posix_symlink,
10889 METH_VARARGS | METH_KEYWORDS,
10890 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010891#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010892#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010893 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010894#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010896#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010898#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010899 {"unlink", (PyCFunction)posix_unlink,
10900 METH_VARARGS | METH_KEYWORDS,
10901 posix_unlink__doc__},
10902 {"remove", (PyCFunction)posix_unlink,
10903 METH_VARARGS | METH_KEYWORDS,
10904 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010905 {"utime", (PyCFunction)posix_utime,
10906 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010907#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010908 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010909#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010911#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010912 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010913 {"execve", (PyCFunction)posix_execve,
10914 METH_VARARGS | METH_KEYWORDS,
10915 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010916#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010917#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10919 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010920#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10922 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010923#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010924#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010925#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010927#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010928#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010929 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010930#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010931#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010932#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010933 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10934 {"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 +020010935#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010936#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010937 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010938#endif
10939#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010940 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010941#endif
10942#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010943 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010944#endif
10945#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010946 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010947#endif
10948#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010949 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010950#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010951 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010952#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010953 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10954 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10955#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010956#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010957#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010958 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010959#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010960#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010961 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010962#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010963#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010965#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010966#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010968#endif /* HAVE_GETEUID */
10969#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010971#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010972#ifdef HAVE_GETGROUPLIST
10973 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10974#endif
Fred Drakec9680921999-12-13 16:37:25 +000010975#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010977#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010978 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010979#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010980 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010981#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010982#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010983 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010984#endif /* HAVE_GETPPID */
10985#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010986 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010987#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010988#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010989 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010990#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010991#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010993#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010994#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010996#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010997#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010999#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011000#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11002 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011003#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011004#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011005 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011006#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011007#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011009#endif /* HAVE_SETEUID */
11010#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011012#endif /* HAVE_SETEGID */
11013#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011014 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011015#endif /* HAVE_SETREUID */
11016#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011018#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011019#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011021#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011022#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011024#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011025#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011027#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011028#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011030#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011031#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011033#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011034#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011036#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011037#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011038 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011039#endif /* HAVE_WAIT3 */
11040#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011041 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011042#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011043#if defined(HAVE_WAITID) && !defined(__APPLE__)
11044 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11045#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011046#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011048#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011049#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011051#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011052#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011054#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011055#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011057#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011058#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011060#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011061#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011063#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011064 {"open", (PyCFunction)posix_open,\
11065 METH_VARARGS | METH_KEYWORDS,
11066 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11068 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11069 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11070 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11071 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011072#ifdef HAVE_LOCKF
11073 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11074#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11076 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011077#ifdef HAVE_READV
11078 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11079#endif
11080#ifdef HAVE_PREAD
11081 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11082#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011083 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011084#ifdef HAVE_WRITEV
11085 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11086#endif
11087#ifdef HAVE_PWRITE
11088 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11089#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011090#ifdef HAVE_SENDFILE
11091 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11092 posix_sendfile__doc__},
11093#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011094 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011096#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011098#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011099#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011100 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011101#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011102#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011103 {"mkfifo", (PyCFunction)posix_mkfifo,
11104 METH_VARARGS | METH_KEYWORDS,
11105 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011106#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011107#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011108 {"mknod", (PyCFunction)posix_mknod,
11109 METH_VARARGS | METH_KEYWORDS,
11110 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011111#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011112#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11114 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11115 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011116#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011117#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011119#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011120#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011121 {"truncate", (PyCFunction)posix_truncate,
11122 METH_VARARGS | METH_KEYWORDS,
11123 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011124#endif
11125#ifdef HAVE_POSIX_FALLOCATE
11126 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11127#endif
11128#ifdef HAVE_POSIX_FADVISE
11129 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11130#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011131#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011133#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011134#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011136#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011138#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011140#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011141#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011143#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011144#ifdef HAVE_SYNC
11145 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11146#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011147#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011149#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011150#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011151#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011153#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011154#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011156#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011157#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011159#endif /* WIFSTOPPED */
11160#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011162#endif /* WIFSIGNALED */
11163#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011165#endif /* WIFEXITED */
11166#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011168#endif /* WEXITSTATUS */
11169#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011171#endif /* WTERMSIG */
11172#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011174#endif /* WSTOPSIG */
11175#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011176#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011178#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011179#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011180 {"statvfs", (PyCFunction)posix_statvfs,
11181 METH_VARARGS | METH_KEYWORDS,
11182 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011183#endif
Fred Drakec9680921999-12-13 16:37:25 +000011184#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011186#endif
11187#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011189#endif
11190#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011191 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011192#endif
11193#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011194 {"pathconf", (PyCFunction)posix_pathconf,
11195 METH_VARARGS | METH_KEYWORDS,
11196 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011197#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011198 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011199#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011200 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011201 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011202 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011203 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011204 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011205#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011206#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011207 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011208#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011209 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011210#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011212#endif
11213#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011215#endif
11216#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011218#endif
11219#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011221#endif
11222
Benjamin Peterson9428d532011-09-14 11:45:52 -040011223#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011224 {"setxattr", (PyCFunction)posix_setxattr,
11225 METH_VARARGS | METH_KEYWORDS,
11226 posix_setxattr__doc__},
11227 {"getxattr", (PyCFunction)posix_getxattr,
11228 METH_VARARGS | METH_KEYWORDS,
11229 posix_getxattr__doc__},
11230 {"removexattr", (PyCFunction)posix_removexattr,
11231 METH_VARARGS | METH_KEYWORDS,
11232 posix_removexattr__doc__},
11233 {"listxattr", (PyCFunction)posix_listxattr,
11234 METH_VARARGS | METH_KEYWORDS,
11235 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011236#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011237#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11238 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11239#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011240 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011241};
11242
11243
Barry Warsaw4a342091996-12-19 23:50:02 +000011244static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011245ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011246{
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011248}
11249
Guido van Rossumd48f2521997-12-05 22:19:34 +000011250#if defined(PYOS_OS2)
11251/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011252static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011253{
11254 APIRET rc;
11255 ULONG values[QSV_MAX+1];
11256 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011257 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011258
11259 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011260 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011261 Py_END_ALLOW_THREADS
11262
11263 if (rc != NO_ERROR) {
11264 os2_error(rc);
11265 return -1;
11266 }
11267
Fred Drake4d1e64b2002-04-15 19:40:07 +000011268 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11269 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11270 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11271 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11272 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11273 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11274 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011275
11276 switch (values[QSV_VERSION_MINOR]) {
11277 case 0: ver = "2.00"; break;
11278 case 10: ver = "2.10"; break;
11279 case 11: ver = "2.11"; break;
11280 case 30: ver = "3.00"; break;
11281 case 40: ver = "4.00"; break;
11282 case 50: ver = "5.00"; break;
11283 default:
Tim Peters885d4572001-11-28 20:27:42 +000011284 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011286 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011287 ver = &tmp[0];
11288 }
11289
11290 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011291 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011292 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011293
11294 /* Add Indicator of Which Drive was Used to Boot the System */
11295 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11296 tmp[1] = ':';
11297 tmp[2] = '\0';
11298
Fred Drake4d1e64b2002-04-15 19:40:07 +000011299 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011300}
11301#endif
11302
Brian Curtin52173d42010-12-02 18:29:18 +000011303#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011304static int
Brian Curtin52173d42010-12-02 18:29:18 +000011305enable_symlink()
11306{
11307 HANDLE tok;
11308 TOKEN_PRIVILEGES tok_priv;
11309 LUID luid;
11310 int meth_idx = 0;
11311
11312 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011313 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011314
11315 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011316 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011317
11318 tok_priv.PrivilegeCount = 1;
11319 tok_priv.Privileges[0].Luid = luid;
11320 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11321
11322 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11323 sizeof(TOKEN_PRIVILEGES),
11324 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011325 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011326
Brian Curtin3b4499c2010-12-28 14:31:47 +000011327 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11328 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011329}
11330#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11331
Barry Warsaw4a342091996-12-19 23:50:02 +000011332static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011333all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011334{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011335#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011337#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011338#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011339 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011340#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011341#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011342 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011343#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011344#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011345 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011346#endif
Fred Drakec9680921999-12-13 16:37:25 +000011347#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011349#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011350#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011352#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011353#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011355#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011356#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011358#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011359#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011361#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011362#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011364#endif
11365#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011367#endif
11368#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011370#endif
11371#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011373#endif
11374#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011376#endif
11377#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011379#endif
11380#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011382#endif
11383#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011385#endif
11386#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011388#endif
11389#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011391#endif
11392#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011394#endif
11395#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011397#endif
11398#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011400#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011401#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011403#endif
11404#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011406#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011407#ifdef O_XATTR
11408 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11409#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011410#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011412#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011413#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011415#endif
11416#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011418#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011419#ifdef O_EXEC
11420 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11421#endif
11422#ifdef O_SEARCH
11423 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11424#endif
11425#ifdef O_TTY_INIT
11426 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11427#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011428#ifdef PRIO_PROCESS
11429 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11430#endif
11431#ifdef PRIO_PGRP
11432 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11433#endif
11434#ifdef PRIO_USER
11435 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11436#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011437#ifdef O_CLOEXEC
11438 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11439#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011440#ifdef O_ACCMODE
11441 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11442#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011443
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011444
Jesus Cea94363612012-06-22 18:32:07 +020011445#ifdef SEEK_HOLE
11446 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11447#endif
11448#ifdef SEEK_DATA
11449 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11450#endif
11451
Tim Peters5aa91602002-01-30 05:46:57 +000011452/* MS Windows */
11453#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011454 /* Don't inherit in child processes. */
11455 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011456#endif
11457#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011458 /* Optimize for short life (keep in memory). */
11459 /* MS forgot to define this one with a non-underscore form too. */
11460 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011461#endif
11462#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011463 /* Automatically delete when last handle is closed. */
11464 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011465#endif
11466#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011467 /* Optimize for random access. */
11468 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011469#endif
11470#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011471 /* Optimize for sequential access. */
11472 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011473#endif
11474
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011475/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011476#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011477 /* Send a SIGIO signal whenever input or output
11478 becomes available on file descriptor */
11479 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011480#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011481#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011482 /* Direct disk access. */
11483 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011484#endif
11485#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011486 /* Must be a directory. */
11487 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011488#endif
11489#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011490 /* Do not follow links. */
11491 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011492#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011493#ifdef O_NOLINKS
11494 /* Fails if link count of the named file is greater than 1 */
11495 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11496#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011497#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 /* Do not update the access time. */
11499 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011500#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011501
Victor Stinner8c62be82010-05-06 00:08:46 +000011502 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011503#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011505#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011506#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011507 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011508#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011509#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011511#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011512#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011513 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011514#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011515#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011517#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011518#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011520#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011521#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011523#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011524#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011526#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011527#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011529#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011530#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011532#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011533#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011535#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011536#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011538#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011539#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011541#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011542#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011544#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011545#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011547#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011548#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011550#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011551#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011553#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011554
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011555 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011556#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011557 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011558#endif /* ST_RDONLY */
11559#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011560 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011561#endif /* ST_NOSUID */
11562
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011563 /* FreeBSD sendfile() constants */
11564#ifdef SF_NODISKIO
11565 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11566#endif
11567#ifdef SF_MNOWAIT
11568 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11569#endif
11570#ifdef SF_SYNC
11571 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11572#endif
11573
Ross Lagerwall7807c352011-03-17 20:20:30 +020011574 /* constants for posix_fadvise */
11575#ifdef POSIX_FADV_NORMAL
11576 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11577#endif
11578#ifdef POSIX_FADV_SEQUENTIAL
11579 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11580#endif
11581#ifdef POSIX_FADV_RANDOM
11582 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11583#endif
11584#ifdef POSIX_FADV_NOREUSE
11585 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11586#endif
11587#ifdef POSIX_FADV_WILLNEED
11588 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11589#endif
11590#ifdef POSIX_FADV_DONTNEED
11591 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11592#endif
11593
11594 /* constants for waitid */
11595#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11596 if (ins(d, "P_PID", (long)P_PID)) return -1;
11597 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11598 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11599#endif
11600#ifdef WEXITED
11601 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11602#endif
11603#ifdef WNOWAIT
11604 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11605#endif
11606#ifdef WSTOPPED
11607 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11608#endif
11609#ifdef CLD_EXITED
11610 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11611#endif
11612#ifdef CLD_DUMPED
11613 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11614#endif
11615#ifdef CLD_TRAPPED
11616 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11617#endif
11618#ifdef CLD_CONTINUED
11619 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11620#endif
11621
11622 /* constants for lockf */
11623#ifdef F_LOCK
11624 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11625#endif
11626#ifdef F_TLOCK
11627 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11628#endif
11629#ifdef F_ULOCK
11630 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11631#endif
11632#ifdef F_TEST
11633 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11634#endif
11635
Guido van Rossum246bc171999-02-01 23:54:31 +000011636#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011637#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011638 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11639 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11640 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11641 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11642 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11643 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11644 if (ins(d, "P_PM", (long)P_PM)) return -1;
11645 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11646 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11647 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11648 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11649 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11650 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11651 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11652 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11653 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11654 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11655 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11656 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11657 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011658#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011659 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11660 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11661 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11662 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11663 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011664#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011665#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011666
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011667#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011668 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011669 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11670 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11671#ifdef SCHED_SPORADIC
11672 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11673#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011674#ifdef SCHED_BATCH
11675 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11676#endif
11677#ifdef SCHED_IDLE
11678 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11679#endif
11680#ifdef SCHED_RESET_ON_FORK
11681 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11682#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011683#ifdef SCHED_SYS
11684 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11685#endif
11686#ifdef SCHED_IA
11687 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11688#endif
11689#ifdef SCHED_FSS
11690 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11691#endif
11692#ifdef SCHED_FX
11693 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11694#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011695#endif
11696
Benjamin Peterson9428d532011-09-14 11:45:52 -040011697#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011698 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11699 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11700 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11701#endif
11702
Victor Stinner8b905bd2011-10-25 13:34:04 +020011703#ifdef RTLD_LAZY
11704 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11705#endif
11706#ifdef RTLD_NOW
11707 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11708#endif
11709#ifdef RTLD_GLOBAL
11710 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11711#endif
11712#ifdef RTLD_LOCAL
11713 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11714#endif
11715#ifdef RTLD_NODELETE
11716 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11717#endif
11718#ifdef RTLD_NOLOAD
11719 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11720#endif
11721#ifdef RTLD_DEEPBIND
11722 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11723#endif
11724
Guido van Rossumd48f2521997-12-05 22:19:34 +000011725#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011726 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011727#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011728 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011729}
11730
11731
Tim Peters5aa91602002-01-30 05:46:57 +000011732#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011733#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011734#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011735
11736#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011737#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011738#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011739
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011740#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011741#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011742#define MODNAME "posix"
11743#endif
11744
Martin v. Löwis1a214512008-06-11 05:26:20 +000011745static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 PyModuleDef_HEAD_INIT,
11747 MODNAME,
11748 posix__doc__,
11749 -1,
11750 posix_methods,
11751 NULL,
11752 NULL,
11753 NULL,
11754 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011755};
11756
11757
Larry Hastings9cf065c2012-06-22 16:30:09 -070011758static char *have_functions[] = {
11759
11760#ifdef HAVE_FACCESSAT
11761 "HAVE_FACCESSAT",
11762#endif
11763
11764#ifdef HAVE_FCHDIR
11765 "HAVE_FCHDIR",
11766#endif
11767
11768#ifdef HAVE_FCHMOD
11769 "HAVE_FCHMOD",
11770#endif
11771
11772#ifdef HAVE_FCHMODAT
11773 "HAVE_FCHMODAT",
11774#endif
11775
11776#ifdef HAVE_FCHOWN
11777 "HAVE_FCHOWN",
11778#endif
11779
11780#ifdef HAVE_FEXECVE
11781 "HAVE_FEXECVE",
11782#endif
11783
11784#ifdef HAVE_FDOPENDIR
11785 "HAVE_FDOPENDIR",
11786#endif
11787
Georg Brandl306336b2012-06-24 12:55:33 +020011788#ifdef HAVE_FPATHCONF
11789 "HAVE_FPATHCONF",
11790#endif
11791
Larry Hastings9cf065c2012-06-22 16:30:09 -070011792#ifdef HAVE_FSTATAT
11793 "HAVE_FSTATAT",
11794#endif
11795
11796#ifdef HAVE_FSTATVFS
11797 "HAVE_FSTATVFS",
11798#endif
11799
Georg Brandl306336b2012-06-24 12:55:33 +020011800#ifdef HAVE_FTRUNCATE
11801 "HAVE_FTRUNCATE",
11802#endif
11803
Larry Hastings9cf065c2012-06-22 16:30:09 -070011804#ifdef HAVE_FUTIMENS
11805 "HAVE_FUTIMENS",
11806#endif
11807
11808#ifdef HAVE_FUTIMES
11809 "HAVE_FUTIMES",
11810#endif
11811
11812#ifdef HAVE_FUTIMESAT
11813 "HAVE_FUTIMESAT",
11814#endif
11815
11816#ifdef HAVE_LINKAT
11817 "HAVE_LINKAT",
11818#endif
11819
11820#ifdef HAVE_LCHFLAGS
11821 "HAVE_LCHFLAGS",
11822#endif
11823
11824#ifdef HAVE_LCHMOD
11825 "HAVE_LCHMOD",
11826#endif
11827
11828#ifdef HAVE_LCHOWN
11829 "HAVE_LCHOWN",
11830#endif
11831
11832#ifdef HAVE_LSTAT
11833 "HAVE_LSTAT",
11834#endif
11835
11836#ifdef HAVE_LUTIMES
11837 "HAVE_LUTIMES",
11838#endif
11839
11840#ifdef HAVE_MKDIRAT
11841 "HAVE_MKDIRAT",
11842#endif
11843
11844#ifdef HAVE_MKFIFOAT
11845 "HAVE_MKFIFOAT",
11846#endif
11847
11848#ifdef HAVE_MKNODAT
11849 "HAVE_MKNODAT",
11850#endif
11851
11852#ifdef HAVE_OPENAT
11853 "HAVE_OPENAT",
11854#endif
11855
11856#ifdef HAVE_READLINKAT
11857 "HAVE_READLINKAT",
11858#endif
11859
11860#ifdef HAVE_RENAMEAT
11861 "HAVE_RENAMEAT",
11862#endif
11863
11864#ifdef HAVE_SYMLINKAT
11865 "HAVE_SYMLINKAT",
11866#endif
11867
11868#ifdef HAVE_UNLINKAT
11869 "HAVE_UNLINKAT",
11870#endif
11871
11872#ifdef HAVE_UTIMENSAT
11873 "HAVE_UTIMENSAT",
11874#endif
11875
11876#ifdef MS_WINDOWS
11877 "MS_WINDOWS",
11878#endif
11879
11880 NULL
11881};
11882
11883
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011884PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011885INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011886{
Victor Stinner8c62be82010-05-06 00:08:46 +000011887 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011888 PyObject *list;
11889 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011890
Brian Curtin52173d42010-12-02 18:29:18 +000011891#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011892 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011893#endif
11894
Victor Stinner8c62be82010-05-06 00:08:46 +000011895 m = PyModule_Create(&posixmodule);
11896 if (m == NULL)
11897 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011898
Victor Stinner8c62be82010-05-06 00:08:46 +000011899 /* Initialize environ dictionary */
11900 v = convertenviron();
11901 Py_XINCREF(v);
11902 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11903 return NULL;
11904 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011905
Victor Stinner8c62be82010-05-06 00:08:46 +000011906 if (all_ins(m))
11907 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011908
Victor Stinner8c62be82010-05-06 00:08:46 +000011909 if (setup_confname_tables(m))
11910 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011911
Victor Stinner8c62be82010-05-06 00:08:46 +000011912 Py_INCREF(PyExc_OSError);
11913 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011914
Guido van Rossumb3d39562000-01-31 18:41:26 +000011915#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011916 if (posix_putenv_garbage == NULL)
11917 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011918#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011919
Victor Stinner8c62be82010-05-06 00:08:46 +000011920 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011921#if defined(HAVE_WAITID) && !defined(__APPLE__)
11922 waitid_result_desc.name = MODNAME ".waitid_result";
11923 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11924#endif
11925
Victor Stinner8c62be82010-05-06 00:08:46 +000011926 stat_result_desc.name = MODNAME ".stat_result";
11927 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11928 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11929 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11930 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11931 structseq_new = StatResultType.tp_new;
11932 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011933
Victor Stinner8c62be82010-05-06 00:08:46 +000011934 statvfs_result_desc.name = MODNAME ".statvfs_result";
11935 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011936#ifdef NEED_TICKS_PER_SECOND
11937# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011938 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011939# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011940 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011941# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011942 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011943# endif
11944#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011945
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011946#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011947 sched_param_desc.name = MODNAME ".sched_param";
11948 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11949 SchedParamType.tp_new = sched_param_new;
11950#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011951
11952 /* initialize TerminalSize_info */
11953 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011954 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011955#if defined(HAVE_WAITID) && !defined(__APPLE__)
11956 Py_INCREF((PyObject*) &WaitidResultType);
11957 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11958#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011959 Py_INCREF((PyObject*) &StatResultType);
11960 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11961 Py_INCREF((PyObject*) &StatVFSResultType);
11962 PyModule_AddObject(m, "statvfs_result",
11963 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011964
11965#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011966 Py_INCREF(&SchedParamType);
11967 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011968#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011969
Larry Hastings605a62d2012-06-24 04:33:36 -070011970 times_result_desc.name = MODNAME ".times_result";
11971 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11972 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11973
11974 uname_result_desc.name = MODNAME ".uname_result";
11975 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11976 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11977
Thomas Wouters477c8d52006-05-27 19:21:47 +000011978#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011979 /*
11980 * Step 2 of weak-linking support on Mac OS X.
11981 *
11982 * The code below removes functions that are not available on the
11983 * currently active platform.
11984 *
11985 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011986 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011987 * OSX 10.4.
11988 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011989#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011990 if (fstatvfs == NULL) {
11991 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11992 return NULL;
11993 }
11994 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011995#endif /* HAVE_FSTATVFS */
11996
11997#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011998 if (statvfs == NULL) {
11999 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12000 return NULL;
12001 }
12002 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012003#endif /* HAVE_STATVFS */
12004
12005# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012006 if (lchown == NULL) {
12007 if (PyObject_DelAttrString(m, "lchown") == -1) {
12008 return NULL;
12009 }
12010 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012011#endif /* HAVE_LCHOWN */
12012
12013
12014#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012015
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012016 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012017 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12018
Larry Hastings6fe20b32012-04-19 15:07:49 -070012019 billion = PyLong_FromLong(1000000000);
12020 if (!billion)
12021 return NULL;
12022
Larry Hastings9cf065c2012-06-22 16:30:09 -070012023 /* suppress "function not used" warnings */
12024 {
12025 int ignored;
12026 fd_specified("", -1);
12027 follow_symlinks_specified("", 1);
12028 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12029 dir_fd_converter(Py_None, &ignored);
12030 dir_fd_unavailable(Py_None, &ignored);
12031 }
12032
12033 /*
12034 * provide list of locally available functions
12035 * so os.py can populate support_* lists
12036 */
12037 list = PyList_New(0);
12038 if (!list)
12039 return NULL;
12040 for (trace = have_functions; *trace; trace++) {
12041 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12042 if (!unicode)
12043 return NULL;
12044 if (PyList_Append(list, unicode))
12045 return NULL;
12046 Py_DECREF(unicode);
12047 }
12048 PyModule_AddObject(m, "_have_functions", list);
12049
12050 initialized = 1;
12051
Victor Stinner8c62be82010-05-06 00:08:46 +000012052 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012053
Guido van Rossumb6775db1994-08-01 11:34:53 +000012054}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012055
12056#ifdef __cplusplus
12057}
12058#endif