blob: 551af2f5a8c6c3715ce0a55e0c5ceefb089d0c63 [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;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200440 long result;
441 if (PyFloat_Check(obj)) {
442 PyErr_SetString(PyExc_TypeError,
443 "integer argument expected, got float");
444 return 0;
445 }
446 result = PyLong_AsLongAndOverflow(obj, &overflow);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200447 if (overflow < 0)
448 goto OverflowDown;
449 if (!overflow && result == -1) {
450 /* error or -1 */
451 if (PyErr_Occurred())
452 return 0;
453 *(uid_t *)p = (uid_t)-1;
454 }
455 else {
456 /* unsigned uid_t */
457 unsigned long uresult;
458 if (overflow > 0) {
459 uresult = PyLong_AsUnsignedLong(obj);
460 if (PyErr_Occurred()) {
461 if (PyErr_ExceptionMatches(PyExc_OverflowError))
462 goto OverflowUp;
463 return 0;
464 }
465 if ((uid_t)uresult == (uid_t)-1)
466 goto OverflowUp;
467 } else {
468 if (result < 0)
469 goto OverflowDown;
470 uresult = result;
471 }
472 if (sizeof(uid_t) < sizeof(long) &&
473 (unsigned long)(uid_t)uresult != uresult)
474 goto OverflowUp;
475 *(uid_t *)p = (uid_t)uresult;
476 }
477 return 1;
478
479OverflowDown:
480 PyErr_SetString(PyExc_OverflowError,
481 "user id is less than minimum");
482 return 0;
483
484OverflowUp:
485 PyErr_SetString(PyExc_OverflowError,
486 "user id is greater than maximum");
487 return 0;
488}
489
490int
491_Py_Gid_Converter(PyObject *obj, void *p)
492{
493 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200494 long result;
495 if (PyFloat_Check(obj)) {
496 PyErr_SetString(PyExc_TypeError,
497 "integer argument expected, got float");
498 return 0;
499 }
500 result = PyLong_AsLongAndOverflow(obj, &overflow);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200501 if (overflow < 0)
502 goto OverflowDown;
503 if (!overflow && result == -1) {
504 /* error or -1 */
505 if (PyErr_Occurred())
506 return 0;
507 *(gid_t *)p = (gid_t)-1;
508 }
509 else {
510 /* unsigned gid_t */
511 unsigned long uresult;
512 if (overflow > 0) {
513 uresult = PyLong_AsUnsignedLong(obj);
514 if (PyErr_Occurred()) {
515 if (PyErr_ExceptionMatches(PyExc_OverflowError))
516 goto OverflowUp;
517 return 0;
518 }
519 if ((gid_t)uresult == (gid_t)-1)
520 goto OverflowUp;
521 } else {
522 if (result < 0)
523 goto OverflowDown;
524 uresult = result;
525 }
526 if (sizeof(gid_t) < sizeof(long) &&
527 (unsigned long)(gid_t)uresult != uresult)
528 goto OverflowUp;
529 *(gid_t *)p = (gid_t)uresult;
530 }
531 return 1;
532
533OverflowDown:
534 PyErr_SetString(PyExc_OverflowError,
535 "group id is less than minimum");
536 return 0;
537
538OverflowUp:
539 PyErr_SetString(PyExc_OverflowError,
540 "group id is greater than maximum");
541 return 0;
542}
543#endif /* MS_WINDOWS */
544
545
Larry Hastings9cf065c2012-06-22 16:30:09 -0700546#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400547/*
548 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
549 * without the int cast, the value gets interpreted as uint (4291925331),
550 * which doesn't play nicely with all the initializer lines in this file that
551 * look like this:
552 * int dir_fd = DEFAULT_DIR_FD;
553 */
554#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700555#else
556#define DEFAULT_DIR_FD (-100)
557#endif
558
559static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200560_fd_converter(PyObject *o, int *p, const char *allowed)
561{
562 int overflow;
563 long long_value = PyLong_AsLongAndOverflow(o, &overflow);
564 if (PyFloat_Check(o) ||
565 (long_value == -1 && !overflow && PyErr_Occurred())) {
566 PyErr_Clear();
567 PyErr_Format(PyExc_TypeError,
568 "argument should be %s, not %.200s",
569 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700570 return 0;
571 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200572 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700573 PyErr_SetString(PyExc_OverflowError,
574 "signed integer is greater than maximum");
575 return 0;
576 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200577 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700578 PyErr_SetString(PyExc_OverflowError,
579 "signed integer is less than minimum");
580 return 0;
581 }
582 *p = (int)long_value;
583 return 1;
584}
585
586static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200587dir_fd_converter(PyObject *o, void *p)
588{
589 if (o == Py_None) {
590 *(int *)p = DEFAULT_DIR_FD;
591 return 1;
592 }
593 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700594}
595
596
597
598/*
599 * A PyArg_ParseTuple "converter" function
600 * that handles filesystem paths in the manner
601 * preferred by the os module.
602 *
603 * path_converter accepts (Unicode) strings and their
604 * subclasses, and bytes and their subclasses. What
605 * it does with the argument depends on the platform:
606 *
607 * * On Windows, if we get a (Unicode) string we
608 * extract the wchar_t * and return it; if we get
609 * bytes we extract the char * and return that.
610 *
611 * * On all other platforms, strings are encoded
612 * to bytes using PyUnicode_FSConverter, then we
613 * extract the char * from the bytes object and
614 * return that.
615 *
616 * path_converter also optionally accepts signed
617 * integers (representing open file descriptors) instead
618 * of path strings.
619 *
620 * Input fields:
621 * path.nullable
622 * If nonzero, the path is permitted to be None.
623 * path.allow_fd
624 * If nonzero, the path is permitted to be a file handle
625 * (a signed int) instead of a string.
626 * path.function_name
627 * If non-NULL, path_converter will use that as the name
628 * of the function in error messages.
629 * (If path.argument_name is NULL it omits the function name.)
630 * path.argument_name
631 * If non-NULL, path_converter will use that as the name
632 * of the parameter in error messages.
633 * (If path.argument_name is NULL it uses "path".)
634 *
635 * Output fields:
636 * path.wide
637 * Points to the path if it was expressed as Unicode
638 * and was not encoded. (Only used on Windows.)
639 * path.narrow
640 * Points to the path if it was expressed as bytes,
641 * or it was Unicode and was encoded to bytes.
642 * path.fd
643 * Contains a file descriptor if path.accept_fd was true
644 * and the caller provided a signed integer instead of any
645 * sort of string.
646 *
647 * WARNING: if your "path" parameter is optional, and is
648 * unspecified, path_converter will never get called.
649 * So if you set allow_fd, you *MUST* initialize path.fd = -1
650 * yourself!
651 * path.length
652 * The length of the path in characters, if specified as
653 * a string.
654 * path.object
655 * The original object passed in.
656 * path.cleanup
657 * For internal use only. May point to a temporary object.
658 * (Pay no attention to the man behind the curtain.)
659 *
660 * At most one of path.wide or path.narrow will be non-NULL.
661 * If path was None and path.nullable was set,
662 * or if path was an integer and path.allow_fd was set,
663 * both path.wide and path.narrow will be NULL
664 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200665 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700666 * path_converter takes care to not write to the path_t
667 * unless it's successful. However it must reset the
668 * "cleanup" field each time it's called.
669 *
670 * Use as follows:
671 * path_t path;
672 * memset(&path, 0, sizeof(path));
673 * PyArg_ParseTuple(args, "O&", path_converter, &path);
674 * // ... use values from path ...
675 * path_cleanup(&path);
676 *
677 * (Note that if PyArg_Parse fails you don't need to call
678 * path_cleanup(). However it is safe to do so.)
679 */
680typedef struct {
681 char *function_name;
682 char *argument_name;
683 int nullable;
684 int allow_fd;
685 wchar_t *wide;
686 char *narrow;
687 int fd;
688 Py_ssize_t length;
689 PyObject *object;
690 PyObject *cleanup;
691} path_t;
692
693static void
694path_cleanup(path_t *path) {
695 if (path->cleanup) {
696 Py_DECREF(path->cleanup);
697 path->cleanup = NULL;
698 }
699}
700
701static int
702path_converter(PyObject *o, void *p) {
703 path_t *path = (path_t *)p;
704 PyObject *unicode, *bytes;
705 Py_ssize_t length;
706 char *narrow;
707
708#define FORMAT_EXCEPTION(exc, fmt) \
709 PyErr_Format(exc, "%s%s" fmt, \
710 path->function_name ? path->function_name : "", \
711 path->function_name ? ": " : "", \
712 path->argument_name ? path->argument_name : "path")
713
714 /* Py_CLEANUP_SUPPORTED support */
715 if (o == NULL) {
716 path_cleanup(path);
717 return 1;
718 }
719
720 /* ensure it's always safe to call path_cleanup() */
721 path->cleanup = NULL;
722
723 if (o == Py_None) {
724 if (!path->nullable) {
725 FORMAT_EXCEPTION(PyExc_TypeError,
726 "can't specify None for %s argument");
727 return 0;
728 }
729 path->wide = NULL;
730 path->narrow = NULL;
731 path->length = 0;
732 path->object = o;
733 path->fd = -1;
734 return 1;
735 }
736
737 unicode = PyUnicode_FromObject(o);
738 if (unicode) {
739#ifdef MS_WINDOWS
740 wchar_t *wide;
741 length = PyUnicode_GET_SIZE(unicode);
742 if (length > 32767) {
743 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
744 Py_DECREF(unicode);
745 return 0;
746 }
747
748 wide = PyUnicode_AsUnicode(unicode);
749 if (!wide) {
750 Py_DECREF(unicode);
751 return 0;
752 }
753
754 path->wide = wide;
755 path->narrow = NULL;
756 path->length = length;
757 path->object = o;
758 path->fd = -1;
759 path->cleanup = unicode;
760 return Py_CLEANUP_SUPPORTED;
761#else
762 int converted = PyUnicode_FSConverter(unicode, &bytes);
763 Py_DECREF(unicode);
764 if (!converted)
765 bytes = NULL;
766#endif
767 }
768 else {
769 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200770 if (PyObject_CheckBuffer(o))
771 bytes = PyBytes_FromObject(o);
772 else
773 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700774 if (!bytes) {
775 PyErr_Clear();
776 if (path->allow_fd) {
777 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200778 int result = _fd_converter(o, &fd,
779 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780 if (result) {
781 path->wide = NULL;
782 path->narrow = NULL;
783 path->length = 0;
784 path->object = o;
785 path->fd = fd;
786 return result;
787 }
788 }
789 }
790 }
791
792 if (!bytes) {
793 if (!PyErr_Occurred())
794 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
795 return 0;
796 }
797
798#ifdef MS_WINDOWS
799 if (win32_warn_bytes_api()) {
800 Py_DECREF(bytes);
801 return 0;
802 }
803#endif
804
805 length = PyBytes_GET_SIZE(bytes);
806#ifdef MS_WINDOWS
807 if (length > MAX_PATH) {
808 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
809 Py_DECREF(bytes);
810 return 0;
811 }
812#endif
813
814 narrow = PyBytes_AS_STRING(bytes);
815 if (length != strlen(narrow)) {
816 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
817 Py_DECREF(bytes);
818 return 0;
819 }
820
821 path->wide = NULL;
822 path->narrow = narrow;
823 path->length = length;
824 path->object = o;
825 path->fd = -1;
826 path->cleanup = bytes;
827 return Py_CLEANUP_SUPPORTED;
828}
829
830static void
831argument_unavailable_error(char *function_name, char *argument_name) {
832 PyErr_Format(PyExc_NotImplementedError,
833 "%s%s%s unavailable on this platform",
834 (function_name != NULL) ? function_name : "",
835 (function_name != NULL) ? ": ": "",
836 argument_name);
837}
838
839static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200840dir_fd_unavailable(PyObject *o, void *p)
841{
842 int dir_fd;
843 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700844 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200845 if (dir_fd != DEFAULT_DIR_FD) {
846 argument_unavailable_error(NULL, "dir_fd");
847 return 0;
848 }
849 *(int *)p = dir_fd;
850 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700851}
852
853static int
854fd_specified(char *function_name, int fd) {
855 if (fd == -1)
856 return 0;
857
858 argument_unavailable_error(function_name, "fd");
859 return 1;
860}
861
862static int
863follow_symlinks_specified(char *function_name, int follow_symlinks) {
864 if (follow_symlinks)
865 return 0;
866
867 argument_unavailable_error(function_name, "follow_symlinks");
868 return 1;
869}
870
871static int
872path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
873 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
874 PyErr_Format(PyExc_ValueError,
875 "%s: can't specify dir_fd without matching path",
876 function_name);
877 return 1;
878 }
879 return 0;
880}
881
882static int
883dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
884 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
885 PyErr_Format(PyExc_ValueError,
886 "%s: can't specify both dir_fd and fd",
887 function_name);
888 return 1;
889 }
890 return 0;
891}
892
893static int
894fd_and_follow_symlinks_invalid(char *function_name, int fd,
895 int follow_symlinks) {
896 if ((fd > 0) && (!follow_symlinks)) {
897 PyErr_Format(PyExc_ValueError,
898 "%s: cannot use fd and follow_symlinks together",
899 function_name);
900 return 1;
901 }
902 return 0;
903}
904
905static int
906dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
907 int follow_symlinks) {
908 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
909 PyErr_Format(PyExc_ValueError,
910 "%s: cannot use dir_fd and follow_symlinks together",
911 function_name);
912 return 1;
913 }
914 return 0;
915}
916
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200917/* A helper used by a number of POSIX-only functions */
918#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000919static int
920_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000921{
922#if !defined(HAVE_LARGEFILE_SUPPORT)
923 *((off_t*)addr) = PyLong_AsLong(arg);
924#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000925 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000926#endif
927 if (PyErr_Occurred())
928 return 0;
929 return 1;
930}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200931#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000932
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000933#if defined _MSC_VER && _MSC_VER >= 1400
934/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200935 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000936 * Normally, an invalid fd is likely to be a C program error and therefore
937 * an assertion can be useful, but it does contradict the POSIX standard
938 * which for write(2) states:
939 * "Otherwise, -1 shall be returned and errno set to indicate the error."
940 * "[EBADF] The fildes argument is not a valid file descriptor open for
941 * writing."
942 * Furthermore, python allows the user to enter any old integer
943 * as a fd and should merely raise a python exception on error.
944 * The Microsoft CRT doesn't provide an official way to check for the
945 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000946 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000947 * internal structures involved.
948 * The structures below must be updated for each version of visual studio
949 * according to the file internal.h in the CRT source, until MS comes
950 * up with a less hacky way to do this.
951 * (all of this is to avoid globally modifying the CRT behaviour using
952 * _set_invalid_parameter_handler() and _CrtSetReportMode())
953 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000954/* The actual size of the structure is determined at runtime.
955 * Only the first items must be present.
956 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000957typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000958 intptr_t osfhnd;
959 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000960} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000961
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000962extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000963#define IOINFO_L2E 5
964#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
965#define IOINFO_ARRAYS 64
966#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
967#define FOPEN 0x01
968#define _NO_CONSOLE_FILENO (intptr_t)-2
969
970/* This function emulates what the windows CRT does to validate file handles */
971int
972_PyVerify_fd(int fd)
973{
Victor Stinner8c62be82010-05-06 00:08:46 +0000974 const int i1 = fd >> IOINFO_L2E;
975 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000976
Antoine Pitrou22e41552010-08-15 18:07:50 +0000977 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000978
Victor Stinner8c62be82010-05-06 00:08:46 +0000979 /* Determine the actual size of the ioinfo structure,
980 * as used by the CRT loaded in memory
981 */
982 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
983 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
984 }
985 if (sizeof_ioinfo == 0) {
986 /* This should not happen... */
987 goto fail;
988 }
989
990 /* See that it isn't a special CLEAR fileno */
991 if (fd != _NO_CONSOLE_FILENO) {
992 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
993 * we check pointer validity and other info
994 */
995 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
996 /* finally, check that the file is open */
997 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
998 if (info->osfile & FOPEN) {
999 return 1;
1000 }
1001 }
1002 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001003 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001004 errno = EBADF;
1005 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001006}
1007
1008/* the special case of checking dup2. The target fd must be in a sensible range */
1009static int
1010_PyVerify_fd_dup2(int fd1, int fd2)
1011{
Victor Stinner8c62be82010-05-06 00:08:46 +00001012 if (!_PyVerify_fd(fd1))
1013 return 0;
1014 if (fd2 == _NO_CONSOLE_FILENO)
1015 return 0;
1016 if ((unsigned)fd2 < _NHANDLE_)
1017 return 1;
1018 else
1019 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001020}
1021#else
1022/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1023#define _PyVerify_fd_dup2(A, B) (1)
1024#endif
1025
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001026#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001027/* The following structure was copied from
1028 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1029 include doesn't seem to be present in the Windows SDK (at least as included
1030 with Visual Studio Express). */
1031typedef struct _REPARSE_DATA_BUFFER {
1032 ULONG ReparseTag;
1033 USHORT ReparseDataLength;
1034 USHORT Reserved;
1035 union {
1036 struct {
1037 USHORT SubstituteNameOffset;
1038 USHORT SubstituteNameLength;
1039 USHORT PrintNameOffset;
1040 USHORT PrintNameLength;
1041 ULONG Flags;
1042 WCHAR PathBuffer[1];
1043 } SymbolicLinkReparseBuffer;
1044
1045 struct {
1046 USHORT SubstituteNameOffset;
1047 USHORT SubstituteNameLength;
1048 USHORT PrintNameOffset;
1049 USHORT PrintNameLength;
1050 WCHAR PathBuffer[1];
1051 } MountPointReparseBuffer;
1052
1053 struct {
1054 UCHAR DataBuffer[1];
1055 } GenericReparseBuffer;
1056 };
1057} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1058
1059#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1060 GenericReparseBuffer)
1061#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1062
1063static int
Brian Curtind25aef52011-06-13 15:16:04 -05001064win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001065{
1066 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1067 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1068 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001069
1070 if (0 == DeviceIoControl(
1071 reparse_point_handle,
1072 FSCTL_GET_REPARSE_POINT,
1073 NULL, 0, /* in buffer */
1074 target_buffer, sizeof(target_buffer),
1075 &n_bytes_returned,
1076 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001077 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001078
1079 if (reparse_tag)
1080 *reparse_tag = rdb->ReparseTag;
1081
Brian Curtind25aef52011-06-13 15:16:04 -05001082 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001083}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001084
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001085#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001086
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001087/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001088#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001089/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001090** environ directly, we must obtain it with _NSGetEnviron(). See also
1091** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001092*/
1093#include <crt_externs.h>
1094static char **environ;
1095#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001096extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001097#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001098
Barry Warsaw53699e91996-12-10 23:23:01 +00001099static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001100convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001101{
Victor Stinner8c62be82010-05-06 00:08:46 +00001102 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001103#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001104 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001105#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001106 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001107#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001108#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001109 APIRET rc;
1110 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
1111#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001112
Victor Stinner8c62be82010-05-06 00:08:46 +00001113 d = PyDict_New();
1114 if (d == NULL)
1115 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001116#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001117 if (environ == NULL)
1118 environ = *_NSGetEnviron();
1119#endif
1120#ifdef MS_WINDOWS
1121 /* _wenviron must be initialized in this way if the program is started
1122 through main() instead of wmain(). */
1123 _wgetenv(L"");
1124 if (_wenviron == NULL)
1125 return d;
1126 /* This part ignores errors */
1127 for (e = _wenviron; *e != NULL; e++) {
1128 PyObject *k;
1129 PyObject *v;
1130 wchar_t *p = wcschr(*e, L'=');
1131 if (p == NULL)
1132 continue;
1133 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1134 if (k == NULL) {
1135 PyErr_Clear();
1136 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001137 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001138 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1139 if (v == NULL) {
1140 PyErr_Clear();
1141 Py_DECREF(k);
1142 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001143 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001144 if (PyDict_GetItem(d, k) == NULL) {
1145 if (PyDict_SetItem(d, k, v) != 0)
1146 PyErr_Clear();
1147 }
1148 Py_DECREF(k);
1149 Py_DECREF(v);
1150 }
1151#else
1152 if (environ == NULL)
1153 return d;
1154 /* This part ignores errors */
1155 for (e = environ; *e != NULL; e++) {
1156 PyObject *k;
1157 PyObject *v;
1158 char *p = strchr(*e, '=');
1159 if (p == NULL)
1160 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001161 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001162 if (k == NULL) {
1163 PyErr_Clear();
1164 continue;
1165 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001166 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001167 if (v == NULL) {
1168 PyErr_Clear();
1169 Py_DECREF(k);
1170 continue;
1171 }
1172 if (PyDict_GetItem(d, k) == NULL) {
1173 if (PyDict_SetItem(d, k, v) != 0)
1174 PyErr_Clear();
1175 }
1176 Py_DECREF(k);
1177 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001178 }
1179#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001180#if defined(PYOS_OS2)
1181 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1182 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1183 PyObject *v = PyBytes_FromString(buffer);
1184 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1185 Py_DECREF(v);
1186 }
1187 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1188 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1189 PyObject *v = PyBytes_FromString(buffer);
1190 PyDict_SetItemString(d, "ENDLIBPATH", v);
1191 Py_DECREF(v);
1192 }
1193#endif
1194 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195}
1196
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001197/* Set a POSIX-specific error from errno, and return NULL */
1198
Barry Warsawd58d7641998-07-23 16:14:40 +00001199static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001200posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001201{
Victor Stinner8c62be82010-05-06 00:08:46 +00001202 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001203}
Barry Warsawd58d7641998-07-23 16:14:40 +00001204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001205posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001206{
Victor Stinner8c62be82010-05-06 00:08:46 +00001207 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001208}
1209
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001210
Mark Hammondef8b6542001-05-13 08:04:26 +00001211static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001212posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001213{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001214 PyObject *name_str, *rc;
1215 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1216 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001217 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001218 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1219 name_str);
1220 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001221 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001222}
1223
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001224#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001225static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001226win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001227{
Victor Stinner8c62be82010-05-06 00:08:46 +00001228 /* XXX We should pass the function name along in the future.
1229 (winreg.c also wants to pass the function name.)
1230 This would however require an additional param to the
1231 Windows error object, which is non-trivial.
1232 */
1233 errno = GetLastError();
1234 if (filename)
1235 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1236 else
1237 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001238}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001239
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001240static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001241win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001242{
Victor Stinner8c62be82010-05-06 00:08:46 +00001243 /* XXX - see win32_error for comments on 'function' */
1244 errno = GetLastError();
1245 if (filename)
1246 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1247 else
1248 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001249}
1250
Victor Stinnereb5657a2011-09-30 01:44:27 +02001251static PyObject *
1252win32_error_object(char* function, PyObject* filename)
1253{
1254 /* XXX - see win32_error for comments on 'function' */
1255 errno = GetLastError();
1256 if (filename)
1257 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1258 PyExc_WindowsError,
1259 errno,
1260 filename);
1261 else
1262 return PyErr_SetFromWindowsErr(errno);
1263}
1264
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001265#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001266
Larry Hastings9cf065c2012-06-22 16:30:09 -07001267/*
1268 * Some functions return Win32 errors, others only ever use posix_error
1269 * (this is for backwards compatibility with exceptions)
1270 */
1271static PyObject *
1272path_posix_error(char *function_name, path_t *path)
1273{
1274 if (path->narrow)
1275 return posix_error_with_filename(path->narrow);
1276 return posix_error();
1277}
1278
1279static PyObject *
1280path_error(char *function_name, path_t *path)
1281{
1282#ifdef MS_WINDOWS
1283 if (path->narrow)
1284 return win32_error(function_name, path->narrow);
1285 if (path->wide)
1286 return win32_error_unicode(function_name, path->wide);
1287 return win32_error(function_name, NULL);
1288#else
1289 return path_posix_error(function_name, path);
1290#endif
1291}
1292
Guido van Rossumd48f2521997-12-05 22:19:34 +00001293#if defined(PYOS_OS2)
1294/**********************************************************************
1295 * Helper Function to Trim and Format OS/2 Messages
1296 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001297static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001298os2_formatmsg(char *msgbuf, int msglen, char *reason)
1299{
1300 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1301
1302 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1303 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1304
Antoine Pitrou4de74572013-02-09 23:11:27 +01001305 while (lastc > msgbuf && Py_ISSPACE(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001306 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1307 }
1308
1309 /* Add Optional Reason Text */
1310 if (reason) {
1311 strcat(msgbuf, " : ");
1312 strcat(msgbuf, reason);
1313 }
1314}
1315
1316/**********************************************************************
1317 * Decode an OS/2 Operating System Error Code
1318 *
1319 * A convenience function to lookup an OS/2 error code and return a
1320 * text message we can use to raise a Python exception.
1321 *
1322 * Notes:
1323 * The messages for errors returned from the OS/2 kernel reside in
1324 * the file OSO001.MSG in the \OS2 directory hierarchy.
1325 *
1326 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001327static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001328os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1329{
1330 APIRET rc;
1331 ULONG msglen;
1332
1333 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1334 Py_BEGIN_ALLOW_THREADS
1335 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1336 errorcode, "oso001.msg", &msglen);
1337 Py_END_ALLOW_THREADS
1338
1339 if (rc == NO_ERROR)
1340 os2_formatmsg(msgbuf, msglen, reason);
1341 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001342 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001344
1345 return msgbuf;
1346}
1347
1348/* Set an OS/2-specific error and return NULL. OS/2 kernel
1349 errors are not in a global variable e.g. 'errno' nor are
1350 they congruent with posix error numbers. */
1351
Victor Stinner8c62be82010-05-06 00:08:46 +00001352static PyObject *
1353os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001354{
1355 char text[1024];
1356 PyObject *v;
1357
1358 os2_strerror(text, sizeof(text), code, "");
1359
1360 v = Py_BuildValue("(is)", code, text);
1361 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001362 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001363 Py_DECREF(v);
1364 }
1365 return NULL; /* Signal to Python that an Exception is Pending */
1366}
1367
1368#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369
1370/* POSIX generic methods */
1371
Barry Warsaw53699e91996-12-10 23:23:01 +00001372static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001373posix_fildes(PyObject *fdobj, int (*func)(int))
1374{
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 int fd;
1376 int res;
1377 fd = PyObject_AsFileDescriptor(fdobj);
1378 if (fd < 0)
1379 return NULL;
1380 if (!_PyVerify_fd(fd))
1381 return posix_error();
1382 Py_BEGIN_ALLOW_THREADS
1383 res = (*func)(fd);
1384 Py_END_ALLOW_THREADS
1385 if (res < 0)
1386 return posix_error();
1387 Py_INCREF(Py_None);
1388 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001389}
Guido van Rossum21142a01999-01-08 21:05:37 +00001390
1391static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393{
Victor Stinner8c62be82010-05-06 00:08:46 +00001394 PyObject *opath1 = NULL;
1395 char *path1;
1396 int res;
1397 if (!PyArg_ParseTuple(args, format,
1398 PyUnicode_FSConverter, &opath1))
1399 return NULL;
1400 path1 = PyBytes_AsString(opath1);
1401 Py_BEGIN_ALLOW_THREADS
1402 res = (*func)(path1);
1403 Py_END_ALLOW_THREADS
1404 if (res < 0)
1405 return posix_error_with_allocated_filename(opath1);
1406 Py_DECREF(opath1);
1407 Py_INCREF(Py_None);
1408 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001409}
1410
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001411
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001412#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001413static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001414win32_1str(PyObject* args, char* func,
1415 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1416 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417{
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001419 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001421
Victor Stinnereb5657a2011-09-30 01:44:27 +02001422 if (PyArg_ParseTuple(args, wformat, &uni))
1423 {
1424 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1425 if (wstr == NULL)
1426 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001427 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001428 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 Py_END_ALLOW_THREADS
1430 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001431 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 Py_INCREF(Py_None);
1433 return Py_None;
1434 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001435 PyErr_Clear();
1436
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 if (!PyArg_ParseTuple(args, format, &ansi))
1438 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001439 if (win32_warn_bytes_api())
1440 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001441 Py_BEGIN_ALLOW_THREADS
1442 result = funcA(ansi);
1443 Py_END_ALLOW_THREADS
1444 if (!result)
1445 return win32_error(func, ansi);
1446 Py_INCREF(Py_None);
1447 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001448
1449}
1450
1451/* This is a reimplementation of the C library's chdir function,
1452 but one that produces Win32 errors instead of DOS error codes.
1453 chdir is essentially a wrapper around SetCurrentDirectory; however,
1454 it also needs to set "magic" environment variables indicating
1455 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001456static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001457win32_chdir(LPCSTR path)
1458{
Victor Stinner8c62be82010-05-06 00:08:46 +00001459 char new_path[MAX_PATH+1];
1460 int result;
1461 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001462
Victor Stinner8c62be82010-05-06 00:08:46 +00001463 if(!SetCurrentDirectoryA(path))
1464 return FALSE;
1465 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1466 if (!result)
1467 return FALSE;
1468 /* In the ANSI API, there should not be any paths longer
1469 than MAX_PATH. */
1470 assert(result <= MAX_PATH+1);
1471 if (strncmp(new_path, "\\\\", 2) == 0 ||
1472 strncmp(new_path, "//", 2) == 0)
1473 /* UNC path, nothing to do. */
1474 return TRUE;
1475 env[1] = new_path[0];
1476 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001477}
1478
1479/* The Unicode version differs from the ANSI version
1480 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001481static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001482win32_wchdir(LPCWSTR path)
1483{
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1485 int result;
1486 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001487
Victor Stinner8c62be82010-05-06 00:08:46 +00001488 if(!SetCurrentDirectoryW(path))
1489 return FALSE;
1490 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1491 if (!result)
1492 return FALSE;
1493 if (result > MAX_PATH+1) {
1494 new_path = malloc(result * sizeof(wchar_t));
1495 if (!new_path) {
1496 SetLastError(ERROR_OUTOFMEMORY);
1497 return FALSE;
1498 }
1499 result = GetCurrentDirectoryW(result, new_path);
1500 if (!result) {
1501 free(new_path);
1502 return FALSE;
1503 }
1504 }
1505 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1506 wcsncmp(new_path, L"//", 2) == 0)
1507 /* UNC path, nothing to do. */
1508 return TRUE;
1509 env[1] = new_path[0];
1510 result = SetEnvironmentVariableW(env, new_path);
1511 if (new_path != _new_path)
1512 free(new_path);
1513 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001514}
1515#endif
1516
Martin v. Löwis14694662006-02-03 12:54:16 +00001517#ifdef MS_WINDOWS
1518/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1519 - time stamps are restricted to second resolution
1520 - file modification times suffer from forth-and-back conversions between
1521 UTC and local time
1522 Therefore, we implement our own stat, based on the Win32 API directly.
1523*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001524#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001525
1526struct win32_stat{
1527 int st_dev;
1528 __int64 st_ino;
1529 unsigned short st_mode;
1530 int st_nlink;
1531 int st_uid;
1532 int st_gid;
1533 int st_rdev;
1534 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001535 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001536 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001537 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001538 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001539 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001540 int st_ctime_nsec;
1541};
1542
1543static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1544
1545static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001546FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001547{
Victor Stinner8c62be82010-05-06 00:08:46 +00001548 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1549 /* Cannot simply cast and dereference in_ptr,
1550 since it might not be aligned properly */
1551 __int64 in;
1552 memcpy(&in, in_ptr, sizeof(in));
1553 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001554 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001555}
1556
Thomas Wouters477c8d52006-05-27 19:21:47 +00001557static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001558time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001559{
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 /* XXX endianness */
1561 __int64 out;
1562 out = time_in + secs_between_epochs;
1563 out = out * 10000000 + nsec_in / 100;
1564 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565}
1566
Martin v. Löwis14694662006-02-03 12:54:16 +00001567/* Below, we *know* that ugo+r is 0444 */
1568#if _S_IREAD != 0400
1569#error Unsupported C library
1570#endif
1571static int
1572attributes_to_mode(DWORD attr)
1573{
Victor Stinner8c62be82010-05-06 00:08:46 +00001574 int m = 0;
1575 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1576 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1577 else
1578 m |= _S_IFREG;
1579 if (attr & FILE_ATTRIBUTE_READONLY)
1580 m |= 0444;
1581 else
1582 m |= 0666;
1583 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001584}
1585
1586static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001587attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001588{
Victor Stinner8c62be82010-05-06 00:08:46 +00001589 memset(result, 0, sizeof(*result));
1590 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1591 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1592 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1593 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1594 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001596 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001597 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1598 /* first clear the S_IFMT bits */
1599 result->st_mode ^= (result->st_mode & 0170000);
1600 /* now set the bits that make this a symlink */
1601 result->st_mode |= 0120000;
1602 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001603
Victor Stinner8c62be82010-05-06 00:08:46 +00001604 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001605}
1606
Guido van Rossumd8faa362007-04-27 19:54:29 +00001607static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001608attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001609{
Victor Stinner8c62be82010-05-06 00:08:46 +00001610 HANDLE hFindFile;
1611 WIN32_FIND_DATAA FileData;
1612 hFindFile = FindFirstFileA(pszFile, &FileData);
1613 if (hFindFile == INVALID_HANDLE_VALUE)
1614 return FALSE;
1615 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001616 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001617 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001618 info->dwFileAttributes = FileData.dwFileAttributes;
1619 info->ftCreationTime = FileData.ftCreationTime;
1620 info->ftLastAccessTime = FileData.ftLastAccessTime;
1621 info->ftLastWriteTime = FileData.ftLastWriteTime;
1622 info->nFileSizeHigh = FileData.nFileSizeHigh;
1623 info->nFileSizeLow = FileData.nFileSizeLow;
1624/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001625 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1626 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001627 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001628}
1629
1630static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001631attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001632{
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 HANDLE hFindFile;
1634 WIN32_FIND_DATAW FileData;
1635 hFindFile = FindFirstFileW(pszFile, &FileData);
1636 if (hFindFile == INVALID_HANDLE_VALUE)
1637 return FALSE;
1638 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001641 info->dwFileAttributes = FileData.dwFileAttributes;
1642 info->ftCreationTime = FileData.ftCreationTime;
1643 info->ftLastAccessTime = FileData.ftLastAccessTime;
1644 info->ftLastWriteTime = FileData.ftLastWriteTime;
1645 info->nFileSizeHigh = FileData.nFileSizeHigh;
1646 info->nFileSizeLow = FileData.nFileSizeLow;
1647/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001648 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1649 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001651}
1652
Brian Curtind25aef52011-06-13 15:16:04 -05001653/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1654static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001655static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1656 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001657static int
Brian Curtind25aef52011-06-13 15:16:04 -05001658check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659{
Brian Curtind25aef52011-06-13 15:16:04 -05001660 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001661 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1662 DWORD);
1663
Brian Curtind25aef52011-06-13 15:16:04 -05001664 /* only recheck */
1665 if (!has_GetFinalPathNameByHandle)
1666 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001667 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001668 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1669 "GetFinalPathNameByHandleA");
1670 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1671 "GetFinalPathNameByHandleW");
1672 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1673 Py_GetFinalPathNameByHandleW;
1674 }
1675 return has_GetFinalPathNameByHandle;
1676}
1677
1678static BOOL
1679get_target_path(HANDLE hdl, wchar_t **target_path)
1680{
1681 int buf_size, result_length;
1682 wchar_t *buf;
1683
1684 /* We have a good handle to the target, use it to determine
1685 the target path name (then we'll call lstat on it). */
1686 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1687 VOLUME_NAME_DOS);
1688 if(!buf_size)
1689 return FALSE;
1690
1691 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001692 if (!buf) {
1693 SetLastError(ERROR_OUTOFMEMORY);
1694 return FALSE;
1695 }
1696
Brian Curtind25aef52011-06-13 15:16:04 -05001697 result_length = Py_GetFinalPathNameByHandleW(hdl,
1698 buf, buf_size, VOLUME_NAME_DOS);
1699
1700 if(!result_length) {
1701 free(buf);
1702 return FALSE;
1703 }
1704
1705 if(!CloseHandle(hdl)) {
1706 free(buf);
1707 return FALSE;
1708 }
1709
1710 buf[result_length] = 0;
1711
1712 *target_path = buf;
1713 return TRUE;
1714}
1715
1716static int
1717win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1718 BOOL traverse);
1719static int
1720win32_xstat_impl(const char *path, struct win32_stat *result,
1721 BOOL traverse)
1722{
Victor Stinner26de69d2011-06-17 15:15:38 +02001723 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001724 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001725 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001727 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001728 const char *dot;
1729
Brian Curtind25aef52011-06-13 15:16:04 -05001730 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001731 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1732 traverse reparse point. */
1733 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001734 }
1735
Brian Curtinf5e76d02010-11-24 13:14:05 +00001736 hFile = CreateFileA(
1737 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001738 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001739 0, /* share mode */
1740 NULL, /* security attributes */
1741 OPEN_EXISTING,
1742 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001743 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1744 Because of this, calls like GetFinalPathNameByHandle will return
1745 the symlink path agin and not the actual final path. */
1746 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1747 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748 NULL);
1749
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001750 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001751 /* Either the target doesn't exist, or we don't have access to
1752 get a handle to it. If the former, we need to return an error.
1753 If the latter, we can use attributes_from_dir. */
1754 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001755 return -1;
1756 /* Could not get attributes on open file. Fall back to
1757 reading the directory. */
1758 if (!attributes_from_dir(path, &info, &reparse_tag))
1759 /* Very strange. This should not fail now */
1760 return -1;
1761 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1762 if (traverse) {
1763 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001764 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001765 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001766 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001768 } else {
1769 if (!GetFileInformationByHandle(hFile, &info)) {
1770 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001771 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 }
1773 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001774 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1775 return -1;
1776
1777 /* Close the outer open file handle now that we're about to
1778 reopen it with different flags. */
1779 if (!CloseHandle(hFile))
1780 return -1;
1781
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001782 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001783 /* In order to call GetFinalPathNameByHandle we need to open
1784 the file without the reparse handling flag set. */
1785 hFile2 = CreateFileA(
1786 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1787 NULL, OPEN_EXISTING,
1788 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1789 NULL);
1790 if (hFile2 == INVALID_HANDLE_VALUE)
1791 return -1;
1792
1793 if (!get_target_path(hFile2, &target_path))
1794 return -1;
1795
1796 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001797 free(target_path);
1798 return code;
1799 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001800 } else
1801 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001802 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001803 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001804
1805 /* Set S_IEXEC if it is an .exe, .bat, ... */
1806 dot = strrchr(path, '.');
1807 if (dot) {
1808 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1809 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1810 result->st_mode |= 0111;
1811 }
1812 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001813}
1814
1815static int
Brian Curtind25aef52011-06-13 15:16:04 -05001816win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1817 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001818{
1819 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001820 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001821 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001822 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001823 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001824 const wchar_t *dot;
1825
Brian Curtind25aef52011-06-13 15:16:04 -05001826 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001827 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1828 traverse reparse point. */
1829 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001830 }
1831
Brian Curtinf5e76d02010-11-24 13:14:05 +00001832 hFile = CreateFileW(
1833 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001834 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001835 0, /* share mode */
1836 NULL, /* security attributes */
1837 OPEN_EXISTING,
1838 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001839 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1840 Because of this, calls like GetFinalPathNameByHandle will return
1841 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001842 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001843 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001844 NULL);
1845
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001846 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001847 /* Either the target doesn't exist, or we don't have access to
1848 get a handle to it. If the former, we need to return an error.
1849 If the latter, we can use attributes_from_dir. */
1850 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001851 return -1;
1852 /* Could not get attributes on open file. Fall back to
1853 reading the directory. */
1854 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1855 /* Very strange. This should not fail now */
1856 return -1;
1857 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1858 if (traverse) {
1859 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001860 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001861 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001862 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001863 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001864 } else {
1865 if (!GetFileInformationByHandle(hFile, &info)) {
1866 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001867 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001868 }
1869 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001870 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1871 return -1;
1872
1873 /* Close the outer open file handle now that we're about to
1874 reopen it with different flags. */
1875 if (!CloseHandle(hFile))
1876 return -1;
1877
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001878 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001879 /* In order to call GetFinalPathNameByHandle we need to open
1880 the file without the reparse handling flag set. */
1881 hFile2 = CreateFileW(
1882 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1883 NULL, OPEN_EXISTING,
1884 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1885 NULL);
1886 if (hFile2 == INVALID_HANDLE_VALUE)
1887 return -1;
1888
1889 if (!get_target_path(hFile2, &target_path))
1890 return -1;
1891
1892 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001893 free(target_path);
1894 return code;
1895 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001896 } else
1897 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001898 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001899 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001900
1901 /* Set S_IEXEC if it is an .exe, .bat, ... */
1902 dot = wcsrchr(path, '.');
1903 if (dot) {
1904 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1905 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1906 result->st_mode |= 0111;
1907 }
1908 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001909}
1910
1911static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001912win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001913{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001914 /* Protocol violation: we explicitly clear errno, instead of
1915 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001916 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001917 errno = 0;
1918 return code;
1919}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001920
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001921static int
1922win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1923{
1924 /* Protocol violation: we explicitly clear errno, instead of
1925 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001926 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001927 errno = 0;
1928 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001929}
Brian Curtind25aef52011-06-13 15:16:04 -05001930/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001931
1932 In Posix, stat automatically traverses symlinks and returns the stat
1933 structure for the target. In Windows, the equivalent GetFileAttributes by
1934 default does not traverse symlinks and instead returns attributes for
1935 the symlink.
1936
1937 Therefore, win32_lstat will get the attributes traditionally, and
1938 win32_stat will first explicitly resolve the symlink target and then will
1939 call win32_lstat on that result.
1940
Ezio Melotti4969f702011-03-15 05:59:46 +02001941 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001942
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001943static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001944win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001945{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001946 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001947}
1948
Victor Stinner8c62be82010-05-06 00:08:46 +00001949static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001950win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001951{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001952 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001953}
1954
1955static int
1956win32_stat(const char* path, struct win32_stat *result)
1957{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001958 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001959}
1960
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001961static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001962win32_stat_w(const wchar_t* path, struct win32_stat *result)
1963{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001964 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001965}
1966
1967static int
1968win32_fstat(int file_number, struct win32_stat *result)
1969{
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 BY_HANDLE_FILE_INFORMATION info;
1971 HANDLE h;
1972 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001973
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001974 if (!_PyVerify_fd(file_number))
1975 h = INVALID_HANDLE_VALUE;
1976 else
1977 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001978
Victor Stinner8c62be82010-05-06 00:08:46 +00001979 /* Protocol violation: we explicitly clear errno, instead of
1980 setting it to a POSIX error. Callers should use GetLastError. */
1981 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001982
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 if (h == INVALID_HANDLE_VALUE) {
1984 /* This is really a C library error (invalid file handle).
1985 We set the Win32 error to the closes one matching. */
1986 SetLastError(ERROR_INVALID_HANDLE);
1987 return -1;
1988 }
1989 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001990
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 type = GetFileType(h);
1992 if (type == FILE_TYPE_UNKNOWN) {
1993 DWORD error = GetLastError();
1994 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001995 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 }
1997 /* else: valid but unknown file */
1998 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001999
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 if (type != FILE_TYPE_DISK) {
2001 if (type == FILE_TYPE_CHAR)
2002 result->st_mode = _S_IFCHR;
2003 else if (type == FILE_TYPE_PIPE)
2004 result->st_mode = _S_IFIFO;
2005 return 0;
2006 }
2007
2008 if (!GetFileInformationByHandle(h, &info)) {
2009 return -1;
2010 }
2011
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002012 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
2015 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00002016}
2017
2018#endif /* MS_WINDOWS */
2019
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002020PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002021"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002022This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002023 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002024or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2025\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002026Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2027or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002028\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002029See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002030
2031static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 {"st_mode", "protection bits"},
2033 {"st_ino", "inode"},
2034 {"st_dev", "device"},
2035 {"st_nlink", "number of hard links"},
2036 {"st_uid", "user ID of owner"},
2037 {"st_gid", "group ID of owner"},
2038 {"st_size", "total size, in bytes"},
2039 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2040 {NULL, "integer time of last access"},
2041 {NULL, "integer time of last modification"},
2042 {NULL, "integer time of last change"},
2043 {"st_atime", "time of last access"},
2044 {"st_mtime", "time of last modification"},
2045 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002046 {"st_atime_ns", "time of last access in nanoseconds"},
2047 {"st_mtime_ns", "time of last modification in nanoseconds"},
2048 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002049#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002051#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002052#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002054#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002055#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002057#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002058#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002059 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002060#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002061#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002063#endif
2064#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002066#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002068};
2069
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002070#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002071#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002072#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002073#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002074#endif
2075
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002076#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002077#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2078#else
2079#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2080#endif
2081
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002082#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002083#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2084#else
2085#define ST_RDEV_IDX ST_BLOCKS_IDX
2086#endif
2087
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002088#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2089#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2090#else
2091#define ST_FLAGS_IDX ST_RDEV_IDX
2092#endif
2093
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002094#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002095#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002096#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002097#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002098#endif
2099
2100#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2101#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2102#else
2103#define ST_BIRTHTIME_IDX ST_GEN_IDX
2104#endif
2105
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002106static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 "stat_result", /* name */
2108 stat_result__doc__, /* doc */
2109 stat_result_fields,
2110 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002111};
2112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002113PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002114"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2115This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002116 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002117or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002118\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002119See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002120
2121static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002122 {"f_bsize", },
2123 {"f_frsize", },
2124 {"f_blocks", },
2125 {"f_bfree", },
2126 {"f_bavail", },
2127 {"f_files", },
2128 {"f_ffree", },
2129 {"f_favail", },
2130 {"f_flag", },
2131 {"f_namemax",},
2132 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002133};
2134
2135static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 "statvfs_result", /* name */
2137 statvfs_result__doc__, /* doc */
2138 statvfs_result_fields,
2139 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002140};
2141
Ross Lagerwall7807c352011-03-17 20:20:30 +02002142#if defined(HAVE_WAITID) && !defined(__APPLE__)
2143PyDoc_STRVAR(waitid_result__doc__,
2144"waitid_result: Result from waitid.\n\n\
2145This object may be accessed either as a tuple of\n\
2146 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2147or via the attributes si_pid, si_uid, and so on.\n\
2148\n\
2149See os.waitid for more information.");
2150
2151static PyStructSequence_Field waitid_result_fields[] = {
2152 {"si_pid", },
2153 {"si_uid", },
2154 {"si_signo", },
2155 {"si_status", },
2156 {"si_code", },
2157 {0}
2158};
2159
2160static PyStructSequence_Desc waitid_result_desc = {
2161 "waitid_result", /* name */
2162 waitid_result__doc__, /* doc */
2163 waitid_result_fields,
2164 5
2165};
2166static PyTypeObject WaitidResultType;
2167#endif
2168
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002169static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002170static PyTypeObject StatResultType;
2171static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002172#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002173static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002174#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002175static newfunc structseq_new;
2176
2177static PyObject *
2178statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2179{
Victor Stinner8c62be82010-05-06 00:08:46 +00002180 PyStructSequence *result;
2181 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002182
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 result = (PyStructSequence*)structseq_new(type, args, kwds);
2184 if (!result)
2185 return NULL;
2186 /* If we have been initialized from a tuple,
2187 st_?time might be set to None. Initialize it
2188 from the int slots. */
2189 for (i = 7; i <= 9; i++) {
2190 if (result->ob_item[i+3] == Py_None) {
2191 Py_DECREF(Py_None);
2192 Py_INCREF(result->ob_item[i]);
2193 result->ob_item[i+3] = result->ob_item[i];
2194 }
2195 }
2196 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002197}
2198
2199
2200
2201/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002202static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002203
2204PyDoc_STRVAR(stat_float_times__doc__,
2205"stat_float_times([newval]) -> oldval\n\n\
2206Determine whether os.[lf]stat represents time stamps as float objects.\n\
2207If newval is True, future calls to stat() return floats, if it is False,\n\
2208future calls return ints. \n\
2209If newval is omitted, return the current setting.\n");
2210
2211static PyObject*
2212stat_float_times(PyObject* self, PyObject *args)
2213{
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 int newval = -1;
2215 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2216 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002217 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2218 "stat_float_times() is deprecated",
2219 1))
2220 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002221 if (newval == -1)
2222 /* Return old value */
2223 return PyBool_FromLong(_stat_float_times);
2224 _stat_float_times = newval;
2225 Py_INCREF(Py_None);
2226 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002227}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002228
Larry Hastings6fe20b32012-04-19 15:07:49 -07002229static PyObject *billion = NULL;
2230
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002231static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002232fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002233{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002234 PyObject *s = _PyLong_FromTime_t(sec);
2235 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2236 PyObject *s_in_ns = NULL;
2237 PyObject *ns_total = NULL;
2238 PyObject *float_s = NULL;
2239
2240 if (!(s && ns_fractional))
2241 goto exit;
2242
2243 s_in_ns = PyNumber_Multiply(s, billion);
2244 if (!s_in_ns)
2245 goto exit;
2246
2247 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2248 if (!ns_total)
2249 goto exit;
2250
Victor Stinner4195b5c2012-02-08 23:03:19 +01002251 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002252 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2253 if (!float_s)
2254 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002255 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002256 else {
2257 float_s = s;
2258 Py_INCREF(float_s);
2259 }
2260
2261 PyStructSequence_SET_ITEM(v, index, s);
2262 PyStructSequence_SET_ITEM(v, index+3, float_s);
2263 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2264 s = NULL;
2265 float_s = NULL;
2266 ns_total = NULL;
2267exit:
2268 Py_XDECREF(s);
2269 Py_XDECREF(ns_fractional);
2270 Py_XDECREF(s_in_ns);
2271 Py_XDECREF(ns_total);
2272 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002273}
2274
Tim Peters5aa91602002-01-30 05:46:57 +00002275/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002276 (used by posix_stat() and posix_fstat()) */
2277static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002278_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002279{
Victor Stinner8c62be82010-05-06 00:08:46 +00002280 unsigned long ansec, mnsec, cnsec;
2281 PyObject *v = PyStructSequence_New(&StatResultType);
2282 if (v == NULL)
2283 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002284
Victor Stinner8c62be82010-05-06 00:08:46 +00002285 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002286#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 PyStructSequence_SET_ITEM(v, 1,
2288 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002289#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002291#endif
2292#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 PyStructSequence_SET_ITEM(v, 2,
2294 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002295#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002296 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002297#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002299#if defined(MS_WINDOWS)
2300 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2301 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2302#else
2303 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2304 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2305#endif
Fred Drake699f3522000-06-29 21:12:41 +00002306#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002307 PyStructSequence_SET_ITEM(v, 6,
2308 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002309#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002310 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002311#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002312
Martin v. Löwis14694662006-02-03 12:54:16 +00002313#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002314 ansec = st->st_atim.tv_nsec;
2315 mnsec = st->st_mtim.tv_nsec;
2316 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002317#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002318 ansec = st->st_atimespec.tv_nsec;
2319 mnsec = st->st_mtimespec.tv_nsec;
2320 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002321#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002322 ansec = st->st_atime_nsec;
2323 mnsec = st->st_mtime_nsec;
2324 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002325#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002326 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002327#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002328 fill_time(v, 7, st->st_atime, ansec);
2329 fill_time(v, 8, st->st_mtime, mnsec);
2330 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002331
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002332#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002333 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2334 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002335#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002336#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002337 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2338 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002339#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002340#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002341 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2342 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002343#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002344#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002345 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2346 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002347#endif
2348#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002349 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002350 PyObject *val;
2351 unsigned long bsec,bnsec;
2352 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002353#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002354 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002355#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002356 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002357#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002358 if (_stat_float_times) {
2359 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2360 } else {
2361 val = PyLong_FromLong((long)bsec);
2362 }
2363 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2364 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002365 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002366#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002367#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002368 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2369 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002370#endif
Fred Drake699f3522000-06-29 21:12:41 +00002371
Victor Stinner8c62be82010-05-06 00:08:46 +00002372 if (PyErr_Occurred()) {
2373 Py_DECREF(v);
2374 return NULL;
2375 }
Fred Drake699f3522000-06-29 21:12:41 +00002376
Victor Stinner8c62be82010-05-06 00:08:46 +00002377 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002378}
2379
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002380/* POSIX methods */
2381
Guido van Rossum94f6f721999-01-06 18:42:14 +00002382
2383static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002384posix_do_stat(char *function_name, path_t *path,
2385 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002386{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002387 STRUCT_STAT st;
2388 int result;
2389
2390#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2391 if (follow_symlinks_specified(function_name, follow_symlinks))
2392 return NULL;
2393#endif
2394
2395 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2396 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2397 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2398 return NULL;
2399
2400 Py_BEGIN_ALLOW_THREADS
2401 if (path->fd != -1)
2402 result = FSTAT(path->fd, &st);
2403 else
2404#ifdef MS_WINDOWS
2405 if (path->wide) {
2406 if (follow_symlinks)
2407 result = win32_stat_w(path->wide, &st);
2408 else
2409 result = win32_lstat_w(path->wide, &st);
2410 }
2411 else
2412#endif
2413#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2414 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2415 result = LSTAT(path->narrow, &st);
2416 else
2417#endif
2418#ifdef HAVE_FSTATAT
2419 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2420 result = fstatat(dir_fd, path->narrow, &st,
2421 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2422 else
2423#endif
2424 result = STAT(path->narrow, &st);
2425 Py_END_ALLOW_THREADS
2426
2427 if (result != 0)
2428 return path_error("stat", path);
2429
2430 return _pystat_fromstructstat(&st);
2431}
2432
2433PyDoc_STRVAR(posix_stat__doc__,
2434"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2435Perform a stat system call on the given path.\n\
2436\n\
2437path may be specified as either a string or as an open file descriptor.\n\
2438\n\
2439If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2440 and path should be relative; path will then be relative to that directory.\n\
2441 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2442 it will raise a NotImplementedError.\n\
2443If follow_symlinks is False, and the last element of the path is a symbolic\n\
2444 link, stat will examine the symbolic link itself instead of the file the\n\
2445 link points to.\n\
2446It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2447 an open file descriptor.");
2448
2449static PyObject *
2450posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2451{
2452 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2453 path_t path;
2454 int dir_fd = DEFAULT_DIR_FD;
2455 int follow_symlinks = 1;
2456 PyObject *return_value;
2457
2458 memset(&path, 0, sizeof(path));
2459 path.allow_fd = 1;
2460 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2461 path_converter, &path,
2462#ifdef HAVE_FSTATAT
2463 dir_fd_converter, &dir_fd,
2464#else
2465 dir_fd_unavailable, &dir_fd,
2466#endif
2467 &follow_symlinks))
2468 return NULL;
2469 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2470 path_cleanup(&path);
2471 return return_value;
2472}
2473
2474PyDoc_STRVAR(posix_lstat__doc__,
2475"lstat(path, *, dir_fd=None) -> stat result\n\n\
2476Like stat(), but do not follow symbolic links.\n\
2477Equivalent to stat(path, follow_symlinks=False).");
2478
2479static PyObject *
2480posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2481{
2482 static char *keywords[] = {"path", "dir_fd", NULL};
2483 path_t path;
2484 int dir_fd = DEFAULT_DIR_FD;
2485 int follow_symlinks = 0;
2486 PyObject *return_value;
2487
2488 memset(&path, 0, sizeof(path));
2489 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2490 path_converter, &path,
2491#ifdef HAVE_FSTATAT
2492 dir_fd_converter, &dir_fd
2493#else
2494 dir_fd_unavailable, &dir_fd
2495#endif
2496 ))
2497 return NULL;
2498 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2499 path_cleanup(&path);
2500 return return_value;
2501}
2502
2503PyDoc_STRVAR(posix_access__doc__,
2504"access(path, mode, *, dir_fd=None, effective_ids=False,\
2505 follow_symlinks=True)\n\n\
2506Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2507False otherwise.\n\
2508\n\
2509If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2510 and path should be relative; path will then be relative to that directory.\n\
2511If effective_ids is True, access will use the effective uid/gid instead of\n\
2512 the real uid/gid.\n\
2513If follow_symlinks is False, and the last element of the path is a symbolic\n\
2514 link, access will examine the symbolic link itself instead of the file the\n\
2515 link points to.\n\
2516dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2517 on your platform. If they are unavailable, using them will raise a\n\
2518 NotImplementedError.\n\
2519\n\
2520Note that most operations will use the effective uid/gid, therefore this\n\
2521 routine can be used in a suid/sgid environment to test if the invoking user\n\
2522 has the specified access to the path.\n\
2523The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2524 of R_OK, W_OK, and X_OK.");
2525
2526static PyObject *
2527posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2528{
2529 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2530 "follow_symlinks", NULL};
2531 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002532 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533 int dir_fd = DEFAULT_DIR_FD;
2534 int effective_ids = 0;
2535 int follow_symlinks = 1;
2536 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002537
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002538#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002539 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002540#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002542#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002543
2544 memset(&path, 0, sizeof(path));
2545 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2546 path_converter, &path, &mode,
2547#ifdef HAVE_FACCESSAT
2548 dir_fd_converter, &dir_fd,
2549#else
2550 dir_fd_unavailable, &dir_fd,
2551#endif
2552 &effective_ids, &follow_symlinks))
2553 return NULL;
2554
2555#ifndef HAVE_FACCESSAT
2556 if (follow_symlinks_specified("access", follow_symlinks))
2557 goto exit;
2558
2559 if (effective_ids) {
2560 argument_unavailable_error("access", "effective_ids");
2561 goto exit;
2562 }
2563#endif
2564
2565#ifdef MS_WINDOWS
2566 Py_BEGIN_ALLOW_THREADS
2567 if (path.wide != NULL)
2568 attr = GetFileAttributesW(path.wide);
2569 else
2570 attr = GetFileAttributesA(path.narrow);
2571 Py_END_ALLOW_THREADS
2572
2573 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002574 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 * * we didn't get a -1, and
2576 * * write access wasn't requested,
2577 * * or the file isn't read-only,
2578 * * or it's a directory.
2579 * (Directories cannot be read-only on Windows.)
2580 */
2581 return_value = PyBool_FromLong(
2582 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002583 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 !(attr & FILE_ATTRIBUTE_READONLY) ||
2585 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2586#else
2587
2588 Py_BEGIN_ALLOW_THREADS
2589#ifdef HAVE_FACCESSAT
2590 if ((dir_fd != DEFAULT_DIR_FD) ||
2591 effective_ids ||
2592 !follow_symlinks) {
2593 int flags = 0;
2594 if (!follow_symlinks)
2595 flags |= AT_SYMLINK_NOFOLLOW;
2596 if (effective_ids)
2597 flags |= AT_EACCESS;
2598 result = faccessat(dir_fd, path.narrow, mode, flags);
2599 }
2600 else
2601#endif
2602 result = access(path.narrow, mode);
2603 Py_END_ALLOW_THREADS
2604 return_value = PyBool_FromLong(!result);
2605#endif
2606
2607#ifndef HAVE_FACCESSAT
2608exit:
2609#endif
2610 path_cleanup(&path);
2611 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002612}
2613
Guido van Rossumd371ff11999-01-25 16:12:23 +00002614#ifndef F_OK
2615#define F_OK 0
2616#endif
2617#ifndef R_OK
2618#define R_OK 4
2619#endif
2620#ifndef W_OK
2621#define W_OK 2
2622#endif
2623#ifndef X_OK
2624#define X_OK 1
2625#endif
2626
2627#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002628PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002629"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002630Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002631
2632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002633posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002634{
Victor Stinner8c62be82010-05-06 00:08:46 +00002635 int id;
2636 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002637
Victor Stinner8c62be82010-05-06 00:08:46 +00002638 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2639 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002640
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002641#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 /* file descriptor 0 only, the default input device (stdin) */
2643 if (id == 0) {
2644 ret = ttyname();
2645 }
2646 else {
2647 ret = NULL;
2648 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002649#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002650 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002651#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 if (ret == NULL)
2653 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002654 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002655}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002656#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002657
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002658#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002659PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002660"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002662
2663static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002664posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002665{
Victor Stinner8c62be82010-05-06 00:08:46 +00002666 char *ret;
2667 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002668
Greg Wardb48bc172000-03-01 21:51:56 +00002669#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002670 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002674 if (ret == NULL)
2675 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002676 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002677}
2678#endif
2679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002680PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002681"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002682Change the current working directory to the specified path.\n\
2683\n\
2684path may always be specified as a string.\n\
2685On some platforms, path may also be specified as an open file descriptor.\n\
2686 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002687
Barry Warsaw53699e91996-12-10 23:23:01 +00002688static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002689posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002690{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002691 path_t path;
2692 int result;
2693 PyObject *return_value = NULL;
2694 static char *keywords[] = {"path", NULL};
2695
2696 memset(&path, 0, sizeof(path));
2697#ifdef HAVE_FCHDIR
2698 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002699#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002700 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2701 path_converter, &path
2702 ))
2703 return NULL;
2704
2705 Py_BEGIN_ALLOW_THREADS
2706#ifdef MS_WINDOWS
2707 if (path.wide)
2708 result = win32_wchdir(path.wide);
2709 else
2710 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002711 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2713 result = _chdir2(path.narrow);
2714#else
2715#ifdef HAVE_FCHDIR
2716 if (path.fd != -1)
2717 result = fchdir(path.fd);
2718 else
2719#endif
2720 result = chdir(path.narrow);
2721#endif
2722 Py_END_ALLOW_THREADS
2723
2724 if (result) {
2725 return_value = path_error("chdir", &path);
2726 goto exit;
2727 }
2728
2729 return_value = Py_None;
2730 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002731
Larry Hastings9cf065c2012-06-22 16:30:09 -07002732exit:
2733 path_cleanup(&path);
2734 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002735}
2736
Fred Drake4d1e64b2002-04-15 19:40:07 +00002737#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002738PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002739"fchdir(fd)\n\n\
2740Change to the directory of the given file descriptor. fd must be\n\
2741opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002742
2743static PyObject *
2744posix_fchdir(PyObject *self, PyObject *fdobj)
2745{
Victor Stinner8c62be82010-05-06 00:08:46 +00002746 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002747}
2748#endif /* HAVE_FCHDIR */
2749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002751PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002752"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2753Change the access permissions of a file.\n\
2754\n\
2755path may always be specified as a string.\n\
2756On some platforms, path may also be specified as an open file descriptor.\n\
2757 If this functionality is unavailable, using it raises an exception.\n\
2758If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2759 and path should be relative; path will then be relative to that directory.\n\
2760If follow_symlinks is False, and the last element of the path is a symbolic\n\
2761 link, chmod will modify the symbolic link itself instead of the file the\n\
2762 link points to.\n\
2763It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2764 an open file descriptor.\n\
2765dir_fd and follow_symlinks may not be implemented on your platform.\n\
2766 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002767
Barry Warsaw53699e91996-12-10 23:23:01 +00002768static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002769posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002770{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771 path_t path;
2772 int mode;
2773 int dir_fd = DEFAULT_DIR_FD;
2774 int follow_symlinks = 1;
2775 int result;
2776 PyObject *return_value = NULL;
2777 static char *keywords[] = {"path", "mode", "dir_fd",
2778 "follow_symlinks", NULL};
2779
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002780#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002781 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002783
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784#ifdef HAVE_FCHMODAT
2785 int fchmodat_nofollow_unsupported = 0;
2786#endif
2787
2788 memset(&path, 0, sizeof(path));
2789#ifdef HAVE_FCHMOD
2790 path.allow_fd = 1;
2791#endif
2792 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2793 path_converter, &path,
2794 &mode,
2795#ifdef HAVE_FCHMODAT
2796 dir_fd_converter, &dir_fd,
2797#else
2798 dir_fd_unavailable, &dir_fd,
2799#endif
2800 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802
2803#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2804 if (follow_symlinks_specified("chmod", follow_symlinks))
2805 goto exit;
2806#endif
2807
2808#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002809 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810 if (path.wide)
2811 attr = GetFileAttributesW(path.wide);
2812 else
2813 attr = GetFileAttributesA(path.narrow);
2814 if (attr == 0xFFFFFFFF)
2815 result = 0;
2816 else {
2817 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 attr &= ~FILE_ATTRIBUTE_READONLY;
2819 else
2820 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002821 if (path.wide)
2822 result = SetFileAttributesW(path.wide, attr);
2823 else
2824 result = SetFileAttributesA(path.narrow, attr);
2825 }
2826 Py_END_ALLOW_THREADS
2827
2828 if (!result) {
2829 return_value = win32_error_object("chmod", path.object);
2830 goto exit;
2831 }
2832#else /* MS_WINDOWS */
2833 Py_BEGIN_ALLOW_THREADS
2834#ifdef HAVE_FCHMOD
2835 if (path.fd != -1)
2836 result = fchmod(path.fd, mode);
2837 else
2838#endif
2839#ifdef HAVE_LCHMOD
2840 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2841 result = lchmod(path.narrow, mode);
2842 else
2843#endif
2844#ifdef HAVE_FCHMODAT
2845 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2846 /*
2847 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2848 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002849 * and then says it isn't implemented yet.
2850 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851 *
2852 * Once it is supported, os.chmod will automatically
2853 * support dir_fd and follow_symlinks=False. (Hopefully.)
2854 * Until then, we need to be careful what exception we raise.
2855 */
2856 result = fchmodat(dir_fd, path.narrow, mode,
2857 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2858 /*
2859 * But wait! We can't throw the exception without allowing threads,
2860 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2861 */
2862 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002863 result &&
2864 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2865 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002866 }
2867 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002868#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869 result = chmod(path.narrow, mode);
2870 Py_END_ALLOW_THREADS
2871
2872 if (result) {
2873#ifdef HAVE_FCHMODAT
2874 if (fchmodat_nofollow_unsupported) {
2875 if (dir_fd != DEFAULT_DIR_FD)
2876 dir_fd_and_follow_symlinks_invalid("chmod",
2877 dir_fd, follow_symlinks);
2878 else
2879 follow_symlinks_specified("chmod", follow_symlinks);
2880 }
2881 else
2882#endif
2883 return_value = path_error("chmod", &path);
2884 goto exit;
2885 }
2886#endif
2887
2888 Py_INCREF(Py_None);
2889 return_value = Py_None;
2890exit:
2891 path_cleanup(&path);
2892 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002893}
2894
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895
Christian Heimes4e30a842007-11-30 22:12:06 +00002896#ifdef HAVE_FCHMOD
2897PyDoc_STRVAR(posix_fchmod__doc__,
2898"fchmod(fd, mode)\n\n\
2899Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002900descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002901
2902static PyObject *
2903posix_fchmod(PyObject *self, PyObject *args)
2904{
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 int fd, mode, res;
2906 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2907 return NULL;
2908 Py_BEGIN_ALLOW_THREADS
2909 res = fchmod(fd, mode);
2910 Py_END_ALLOW_THREADS
2911 if (res < 0)
2912 return posix_error();
2913 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002914}
2915#endif /* HAVE_FCHMOD */
2916
2917#ifdef HAVE_LCHMOD
2918PyDoc_STRVAR(posix_lchmod__doc__,
2919"lchmod(path, mode)\n\n\
2920Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002921affects the link itself rather than the target.\n\
2922Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002923
2924static PyObject *
2925posix_lchmod(PyObject *self, PyObject *args)
2926{
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 PyObject *opath;
2928 char *path;
2929 int i;
2930 int res;
2931 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2932 &opath, &i))
2933 return NULL;
2934 path = PyBytes_AsString(opath);
2935 Py_BEGIN_ALLOW_THREADS
2936 res = lchmod(path, i);
2937 Py_END_ALLOW_THREADS
2938 if (res < 0)
2939 return posix_error_with_allocated_filename(opath);
2940 Py_DECREF(opath);
2941 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002942}
2943#endif /* HAVE_LCHMOD */
2944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002945
Thomas Wouterscf297e42007-02-23 15:07:44 +00002946#ifdef HAVE_CHFLAGS
2947PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948"chflags(path, flags, *, follow_symlinks=True)\n\n\
2949Set file flags.\n\
2950\n\
2951If follow_symlinks is False, and the last element of the path is a symbolic\n\
2952 link, chflags will change flags on the symbolic link itself instead of the\n\
2953 file the link points to.\n\
2954follow_symlinks may not be implemented on your platform. If it is\n\
2955unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002956
2957static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002958posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002959{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002960 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002961 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 int follow_symlinks = 1;
2963 int result;
2964 PyObject *return_value;
2965 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2966
2967 memset(&path, 0, sizeof(path));
2968 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2969 path_converter, &path,
2970 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972
2973#ifndef HAVE_LCHFLAGS
2974 if (follow_symlinks_specified("chflags", follow_symlinks))
2975 goto exit;
2976#endif
2977
Victor Stinner8c62be82010-05-06 00:08:46 +00002978 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979#ifdef HAVE_LCHFLAGS
2980 if (!follow_symlinks)
2981 result = lchflags(path.narrow, flags);
2982 else
2983#endif
2984 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002985 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002986
2987 if (result) {
2988 return_value = path_posix_error("chflags", &path);
2989 goto exit;
2990 }
2991
2992 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994
2995exit:
2996 path_cleanup(&path);
2997 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002998}
2999#endif /* HAVE_CHFLAGS */
3000
3001#ifdef HAVE_LCHFLAGS
3002PyDoc_STRVAR(posix_lchflags__doc__,
3003"lchflags(path, flags)\n\n\
3004Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003005This function will not follow symbolic links.\n\
3006Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003007
3008static PyObject *
3009posix_lchflags(PyObject *self, PyObject *args)
3010{
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 PyObject *opath;
3012 char *path;
3013 unsigned long flags;
3014 int res;
3015 if (!PyArg_ParseTuple(args, "O&k:lchflags",
3016 PyUnicode_FSConverter, &opath, &flags))
3017 return NULL;
3018 path = PyBytes_AsString(opath);
3019 Py_BEGIN_ALLOW_THREADS
3020 res = lchflags(path, flags);
3021 Py_END_ALLOW_THREADS
3022 if (res < 0)
3023 return posix_error_with_allocated_filename(opath);
3024 Py_DECREF(opath);
3025 Py_INCREF(Py_None);
3026 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003027}
3028#endif /* HAVE_LCHFLAGS */
3029
Martin v. Löwis244edc82001-10-04 22:44:26 +00003030#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003032"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003033Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003034
3035static PyObject *
3036posix_chroot(PyObject *self, PyObject *args)
3037{
Victor Stinner8c62be82010-05-06 00:08:46 +00003038 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003039}
3040#endif
3041
Guido van Rossum21142a01999-01-08 21:05:37 +00003042#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003043PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003044"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003045force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003046
3047static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003048posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003049{
Stefan Krah0e803b32010-11-26 16:16:47 +00003050 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003051}
3052#endif /* HAVE_FSYNC */
3053
Ross Lagerwall7807c352011-03-17 20:20:30 +02003054#ifdef HAVE_SYNC
3055PyDoc_STRVAR(posix_sync__doc__,
3056"sync()\n\n\
3057Force write of everything to disk.");
3058
3059static PyObject *
3060posix_sync(PyObject *self, PyObject *noargs)
3061{
3062 Py_BEGIN_ALLOW_THREADS
3063 sync();
3064 Py_END_ALLOW_THREADS
3065 Py_RETURN_NONE;
3066}
3067#endif
3068
Guido van Rossum21142a01999-01-08 21:05:37 +00003069#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003070
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003071#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003072extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3073#endif
3074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003075PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003076"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003077force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003078 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003079
3080static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003081posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003082{
Stefan Krah0e803b32010-11-26 16:16:47 +00003083 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003084}
3085#endif /* HAVE_FDATASYNC */
3086
3087
Fredrik Lundh10723342000-07-10 16:38:09 +00003088#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003089PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3091Change the owner and group id of path to the numeric uid and gid.\n\
3092\n\
3093path may always be specified as a string.\n\
3094On some platforms, path may also be specified as an open file descriptor.\n\
3095 If this functionality is unavailable, using it raises an exception.\n\
3096If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3097 and path should be relative; path will then be relative to that directory.\n\
3098If follow_symlinks is False, and the last element of the path is a symbolic\n\
3099 link, chown will modify the symbolic link itself instead of the file the\n\
3100 link points to.\n\
3101It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3102 an open file descriptor.\n\
3103dir_fd and follow_symlinks may not be implemented on your platform.\n\
3104 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003105
Barry Warsaw53699e91996-12-10 23:23:01 +00003106static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003107posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003108{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003109 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110 uid_t uid;
3111 gid_t gid;
3112 int dir_fd = DEFAULT_DIR_FD;
3113 int follow_symlinks = 1;
3114 int result;
3115 PyObject *return_value = NULL;
3116 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3117 "follow_symlinks", NULL};
3118
3119 memset(&path, 0, sizeof(path));
3120#ifdef HAVE_FCHOWN
3121 path.allow_fd = 1;
3122#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003123 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003125 _Py_Uid_Converter, &uid,
3126 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003127#ifdef HAVE_FCHOWNAT
3128 dir_fd_converter, &dir_fd,
3129#else
3130 dir_fd_unavailable, &dir_fd,
3131#endif
3132 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003133 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003134
3135#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3136 if (follow_symlinks_specified("chown", follow_symlinks))
3137 goto exit;
3138#endif
3139 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3140 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3141 goto exit;
3142
3143#ifdef __APPLE__
3144 /*
3145 * This is for Mac OS X 10.3, which doesn't have lchown.
3146 * (But we still have an lchown symbol because of weak-linking.)
3147 * It doesn't have fchownat either. So there's no possibility
3148 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003149 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003150 if ((!follow_symlinks) && (lchown == NULL)) {
3151 follow_symlinks_specified("chown", follow_symlinks);
3152 goto exit;
3153 }
3154#endif
3155
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157#ifdef HAVE_FCHOWN
3158 if (path.fd != -1)
3159 result = fchown(path.fd, uid, gid);
3160 else
3161#endif
3162#ifdef HAVE_LCHOWN
3163 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3164 result = lchown(path.narrow, uid, gid);
3165 else
3166#endif
3167#ifdef HAVE_FCHOWNAT
3168 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3169 result = fchownat(dir_fd, path.narrow, uid, gid,
3170 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3171 else
3172#endif
3173 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175
3176 if (result) {
3177 return_value = path_posix_error("chown", &path);
3178 goto exit;
3179 }
3180
3181 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003183
3184exit:
3185 path_cleanup(&path);
3186 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003187}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003188#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003189
Christian Heimes4e30a842007-11-30 22:12:06 +00003190#ifdef HAVE_FCHOWN
3191PyDoc_STRVAR(posix_fchown__doc__,
3192"fchown(fd, uid, gid)\n\n\
3193Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003195
3196static PyObject *
3197posix_fchown(PyObject *self, PyObject *args)
3198{
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003200 uid_t uid;
3201 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003203 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3204 _Py_Uid_Converter, &uid,
3205 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003206 return NULL;
3207 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003208 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003209 Py_END_ALLOW_THREADS
3210 if (res < 0)
3211 return posix_error();
3212 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003213}
3214#endif /* HAVE_FCHOWN */
3215
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003216#ifdef HAVE_LCHOWN
3217PyDoc_STRVAR(posix_lchown__doc__,
3218"lchown(path, uid, gid)\n\n\
3219Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003220This function will not follow symbolic links.\n\
3221Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003222
3223static PyObject *
3224posix_lchown(PyObject *self, PyObject *args)
3225{
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 PyObject *opath;
3227 char *path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003228 uid_t uid;
3229 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003231 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 PyUnicode_FSConverter, &opath,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003233 _Py_Uid_Converter, &uid,
3234 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 return NULL;
3236 path = PyBytes_AsString(opath);
3237 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003238 res = lchown(path, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 Py_END_ALLOW_THREADS
3240 if (res < 0)
3241 return posix_error_with_allocated_filename(opath);
3242 Py_DECREF(opath);
3243 Py_INCREF(Py_None);
3244 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003245}
3246#endif /* HAVE_LCHOWN */
3247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003248
Guido van Rossum36bc6801995-06-14 22:54:23 +00003249#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003250static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003251posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003252{
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 char buf[1026];
3254 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003255
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003256#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 if (!use_bytes) {
3258 wchar_t wbuf[1026];
3259 wchar_t *wbuf2 = wbuf;
3260 PyObject *resobj;
3261 DWORD len;
3262 Py_BEGIN_ALLOW_THREADS
3263 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3264 /* If the buffer is large enough, len does not include the
3265 terminating \0. If the buffer is too small, len includes
3266 the space needed for the terminator. */
3267 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3268 wbuf2 = malloc(len * sizeof(wchar_t));
3269 if (wbuf2)
3270 len = GetCurrentDirectoryW(len, wbuf2);
3271 }
3272 Py_END_ALLOW_THREADS
3273 if (!wbuf2) {
3274 PyErr_NoMemory();
3275 return NULL;
3276 }
3277 if (!len) {
3278 if (wbuf2 != wbuf) free(wbuf2);
3279 return win32_error("getcwdu", NULL);
3280 }
3281 resobj = PyUnicode_FromWideChar(wbuf2, len);
3282 if (wbuf2 != wbuf) free(wbuf2);
3283 return resobj;
3284 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003285
3286 if (win32_warn_bytes_api())
3287 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003288#endif
3289
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003291#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003293#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003295#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 Py_END_ALLOW_THREADS
3297 if (res == NULL)
3298 return posix_error();
3299 if (use_bytes)
3300 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003301 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003302}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003303
3304PyDoc_STRVAR(posix_getcwd__doc__,
3305"getcwd() -> path\n\n\
3306Return a unicode string representing the current working directory.");
3307
3308static PyObject *
3309posix_getcwd_unicode(PyObject *self)
3310{
3311 return posix_getcwd(0);
3312}
3313
3314PyDoc_STRVAR(posix_getcwdb__doc__,
3315"getcwdb() -> path\n\n\
3316Return a bytes string representing the current working directory.");
3317
3318static PyObject *
3319posix_getcwd_bytes(PyObject *self)
3320{
3321 return posix_getcwd(1);
3322}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003323#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003324
Larry Hastings9cf065c2012-06-22 16:30:09 -07003325#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3326#define HAVE_LINK 1
3327#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003328
Guido van Rossumb6775db1994-08-01 11:34:53 +00003329#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003330PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003331"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3332Create a hard link to a file.\n\
3333\n\
3334If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3335 descriptor open to a directory, and the respective path string (src or dst)\n\
3336 should be relative; the path will then be relative to that directory.\n\
3337If follow_symlinks is False, and the last element of src is a symbolic\n\
3338 link, link will create a link to the symbolic link itself instead of the\n\
3339 file the link points to.\n\
3340src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3341 platform. If they are unavailable, using them will raise a\n\
3342 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003343
Barry Warsaw53699e91996-12-10 23:23:01 +00003344static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003345posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003346{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003347 path_t src, dst;
3348 int src_dir_fd = DEFAULT_DIR_FD;
3349 int dst_dir_fd = DEFAULT_DIR_FD;
3350 int follow_symlinks = 1;
3351 PyObject *return_value = NULL;
3352 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3353 "follow_symlinks", NULL};
3354#ifdef MS_WINDOWS
3355 BOOL result;
3356#else
3357 int result;
3358#endif
3359
3360 memset(&src, 0, sizeof(src));
3361 memset(&dst, 0, sizeof(dst));
3362 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3363 path_converter, &src,
3364 path_converter, &dst,
3365 dir_fd_converter, &src_dir_fd,
3366 dir_fd_converter, &dst_dir_fd,
3367 &follow_symlinks))
3368 return NULL;
3369
3370#ifndef HAVE_LINKAT
3371 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3372 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3373 goto exit;
3374 }
3375#endif
3376
3377 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3378 PyErr_SetString(PyExc_NotImplementedError,
3379 "link: src and dst must be the same type");
3380 goto exit;
3381 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003382
Brian Curtin1b9df392010-11-24 20:24:31 +00003383#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003384 Py_BEGIN_ALLOW_THREADS
3385 if (src.wide)
3386 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3387 else
3388 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3389 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003390
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 if (!result) {
3392 return_value = win32_error_object("link", dst.object);
3393 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003394 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003395#else
3396 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003397#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3399 (dst_dir_fd != DEFAULT_DIR_FD) ||
3400 (!follow_symlinks))
3401 result = linkat(src_dir_fd, src.narrow,
3402 dst_dir_fd, dst.narrow,
3403 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3404 else
3405#endif
3406 result = link(src.narrow, dst.narrow);
3407 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003408
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409 if (result) {
3410 return_value = path_error("link", &dst);
3411 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003412 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413#endif
3414
3415 return_value = Py_None;
3416 Py_INCREF(Py_None);
3417
3418exit:
3419 path_cleanup(&src);
3420 path_cleanup(&dst);
3421 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003422}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423#endif
3424
Brian Curtin1b9df392010-11-24 20:24:31 +00003425
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003426
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003427PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003428"listdir(path='.') -> list_of_filenames\n\n\
3429Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003430The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431entries '.' and '..' even if they are present in the directory.\n\
3432\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003433path can be specified as either str or bytes. If path is bytes,\n\
3434 the filenames returned will also be bytes; in all other circumstances\n\
3435 the filenames returned will be str.\n\
3436On some platforms, path may also be specified as an open file descriptor;\n\
3437 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003439
Barry Warsaw53699e91996-12-10 23:23:01 +00003440static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003442{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 path_t path;
3444 PyObject *list = NULL;
3445 static char *keywords[] = {"path", NULL};
3446 int fd = -1;
3447
3448#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3449 PyObject *v;
3450 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3451 BOOL result;
3452 WIN32_FIND_DATA FileData;
3453 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3454 char *bufptr = namebuf;
3455 /* only claim to have space for MAX_PATH */
3456 Py_ssize_t len = sizeof(namebuf)-5;
3457 PyObject *po = NULL;
3458 wchar_t *wnamebuf = NULL;
3459#elif defined(PYOS_OS2)
3460#ifndef MAX_PATH
3461#define MAX_PATH CCHMAXPATH
3462#endif
3463 char *pt;
3464 PyObject *v;
3465 char namebuf[MAX_PATH+5];
3466 HDIR hdir = 1;
3467 ULONG srchcnt = 1;
3468 FILEFINDBUF3 ep;
3469 APIRET rc;
3470#else
3471 PyObject *v;
3472 DIR *dirp = NULL;
3473 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003474 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475#endif
3476
3477 memset(&path, 0, sizeof(path));
3478 path.nullable = 1;
3479#ifdef HAVE_FDOPENDIR
3480 path.allow_fd = 1;
3481 path.fd = -1;
3482#endif
3483 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3484 path_converter, &path
3485 ))
3486 return NULL;
3487
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 /* XXX Should redo this putting the (now four) versions of opendir
3489 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003490#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003494
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003496 po_wchars = L".";
3497 len = 1;
3498 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499 po_wchars = path.wide;
3500 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003501 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003503 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3504 if (!wnamebuf) {
3505 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003508 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003510 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 if (wch != L'/' && wch != L'\\' && wch != L':')
3512 wnamebuf[len++] = L'\\';
3513 wcscpy(wnamebuf + len, L"*.*");
3514 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003515 if ((list = PyList_New(0)) == NULL) {
3516 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003518 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003520 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 if (hFindFile == INVALID_HANDLE_VALUE) {
3522 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 if (error == ERROR_FILE_NOT_FOUND)
3524 goto exit;
3525 Py_DECREF(list);
3526 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 }
3530 do {
3531 /* Skip over . and .. */
3532 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3533 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534 v = PyUnicode_FromWideChar(wFileData.cFileName,
3535 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 Py_DECREF(list);
3538 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 break;
3540 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 Py_DECREF(list);
3544 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 break;
3546 }
3547 Py_DECREF(v);
3548 }
3549 Py_BEGIN_ALLOW_THREADS
3550 result = FindNextFileW(hFindFile, &wFileData);
3551 Py_END_ALLOW_THREADS
3552 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3553 it got to the end of the directory. */
3554 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 Py_DECREF(list);
3556 list = win32_error_unicode("FindNextFileW", wnamebuf);
3557 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 }
3559 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003560
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 strcpy(namebuf, path.narrow);
3564 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 if (len > 0) {
3566 char ch = namebuf[len-1];
3567 if (ch != SEP && ch != ALTSEP && ch != ':')
3568 namebuf[len++] = '/';
3569 strcpy(namebuf + len, "*.*");
3570 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003571
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003574
Antoine Pitroub73caab2010-08-09 23:39:31 +00003575 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003577 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 if (hFindFile == INVALID_HANDLE_VALUE) {
3579 int error = GetLastError();
3580 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 goto exit;
3582 Py_DECREF(list);
3583 list = win32_error("FindFirstFile", namebuf);
3584 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 }
3586 do {
3587 /* Skip over . and .. */
3588 if (strcmp(FileData.cFileName, ".") != 0 &&
3589 strcmp(FileData.cFileName, "..") != 0) {
3590 v = PyBytes_FromString(FileData.cFileName);
3591 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 Py_DECREF(list);
3593 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 break;
3595 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003597 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 Py_DECREF(list);
3599 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 break;
3601 }
3602 Py_DECREF(v);
3603 }
3604 Py_BEGIN_ALLOW_THREADS
3605 result = FindNextFile(hFindFile, &FileData);
3606 Py_END_ALLOW_THREADS
3607 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3608 it got to the end of the directory. */
3609 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610 Py_DECREF(list);
3611 list = win32_error("FindNextFile", namebuf);
3612 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 }
3614 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003615
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616exit:
3617 if (hFindFile != INVALID_HANDLE_VALUE) {
3618 if (FindClose(hFindFile) == FALSE) {
3619 if (list != NULL) {
3620 Py_DECREF(list);
3621 list = win32_error_object("FindClose", path.object);
3622 }
3623 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 if (wnamebuf)
3626 free(wnamebuf);
3627 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003628
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003630
Tim Peters0bb44a42000-09-15 07:44:49 +00003631#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003633 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003635 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003637 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003638 if (*pt == ALTSEP)
3639 *pt = SEP;
3640 if (namebuf[len-1] != SEP)
3641 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003642 strcpy(namebuf + len, "*.*");
3643
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 if ((list = PyList_New(0)) == NULL) {
3645 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003646 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003647
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003648 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3649 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003650 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003651 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3652 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3653 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003654
3655 if (rc != NO_ERROR) {
3656 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003657 Py_DECREF(list);
3658 list = posix_error_with_filename(path.narrow);
3659 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003660 }
3661
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003662 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003663 do {
3664 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003665 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003666 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003667
3668 strcpy(namebuf, ep.achName);
3669
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003670 /* Leave Case of Name Alone -- In Native Form */
3671 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003672
Christian Heimes72b710a2008-05-26 13:28:38 +00003673 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003674 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003675 Py_DECREF(list);
3676 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003677 break;
3678 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003680 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 Py_DECREF(list);
3682 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003683 break;
3684 }
3685 Py_DECREF(v);
3686 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3687 }
3688
Larry Hastings9cf065c2012-06-22 16:30:09 -07003689exit:
3690 path_cleanup(&path);
3691
3692 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003693#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003694
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696#ifdef HAVE_FDOPENDIR
3697 if (path.fd != -1) {
3698 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003699 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003700 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003701 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003702
3703 if (fd == -1) {
3704 list = posix_error();
3705 goto exit;
3706 }
3707
Larry Hastingsfdaea062012-06-25 04:42:23 -07003708 return_str = 1;
3709
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 Py_BEGIN_ALLOW_THREADS
3711 dirp = fdopendir(fd);
3712 Py_END_ALLOW_THREADS
3713 }
3714 else
3715#endif
3716 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003717 char *name;
3718 if (path.narrow) {
3719 name = path.narrow;
3720 /* only return bytes if they specified a bytes object */
3721 return_str = !(PyBytes_Check(path.object));
3722 }
3723 else {
3724 name = ".";
3725 return_str = 1;
3726 }
3727
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 Py_BEGIN_ALLOW_THREADS
3729 dirp = opendir(name);
3730 Py_END_ALLOW_THREADS
3731 }
3732
3733 if (dirp == NULL) {
3734 list = path_error("listdir", &path);
3735 goto exit;
3736 }
3737 if ((list = PyList_New(0)) == NULL) {
3738 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 }
3740 for (;;) {
3741 errno = 0;
3742 Py_BEGIN_ALLOW_THREADS
3743 ep = readdir(dirp);
3744 Py_END_ALLOW_THREADS
3745 if (ep == NULL) {
3746 if (errno == 0) {
3747 break;
3748 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003749 Py_DECREF(list);
3750 list = path_error("listdir", &path);
3751 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 }
3753 }
3754 if (ep->d_name[0] == '.' &&
3755 (NAMLEN(ep) == 1 ||
3756 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3757 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003758 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003759 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3760 else
3761 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003762 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 break;
3765 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003766 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003768 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 break;
3770 }
3771 Py_DECREF(v);
3772 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003773
Larry Hastings9cf065c2012-06-22 16:30:09 -07003774exit:
3775 if (dirp != NULL) {
3776 Py_BEGIN_ALLOW_THREADS
3777 if (fd > -1)
3778 rewinddir(dirp);
3779 closedir(dirp);
3780 Py_END_ALLOW_THREADS
3781 }
3782
3783 path_cleanup(&path);
3784
3785 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003786
Tim Peters0bb44a42000-09-15 07:44:49 +00003787#endif /* which OS */
3788} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003789
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003790#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003791/* A helper function for abspath on win32 */
3792static PyObject *
3793posix__getfullpathname(PyObject *self, PyObject *args)
3794{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003795 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003796 char outbuf[MAX_PATH*2];
3797 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003798 PyObject *po;
3799
3800 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3801 {
3802 wchar_t *wpath;
3803 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3804 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003805 DWORD result;
3806 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003807
3808 wpath = PyUnicode_AsUnicode(po);
3809 if (wpath == NULL)
3810 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003811 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003812 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003813 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003814 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003815 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003816 if (!woutbufp)
3817 return PyErr_NoMemory();
3818 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3819 }
3820 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003821 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003822 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003823 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003824 if (woutbufp != woutbuf)
3825 free(woutbufp);
3826 return v;
3827 }
3828 /* Drop the argument parsing error as narrow strings
3829 are also valid. */
3830 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003831
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003832 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3833 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003834 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003835 if (win32_warn_bytes_api())
3836 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003837 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003838 outbuf, &temp)) {
3839 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 return NULL;
3841 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003842 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3843 return PyUnicode_Decode(outbuf, strlen(outbuf),
3844 Py_FileSystemDefaultEncoding, NULL);
3845 }
3846 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003847} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003848
Brian Curtind25aef52011-06-13 15:16:04 -05003849
Brian Curtinf5e76d02010-11-24 13:14:05 +00003850
Brian Curtind40e6f72010-07-08 21:39:08 +00003851/* A helper function for samepath on windows */
3852static PyObject *
3853posix__getfinalpathname(PyObject *self, PyObject *args)
3854{
3855 HANDLE hFile;
3856 int buf_size;
3857 wchar_t *target_path;
3858 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003859 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003860 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003861
Victor Stinnereb5657a2011-09-30 01:44:27 +02003862 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003863 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003864 path = PyUnicode_AsUnicode(po);
3865 if (path == NULL)
3866 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003867
3868 if(!check_GetFinalPathNameByHandle()) {
3869 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3870 NotImplementedError. */
3871 return PyErr_Format(PyExc_NotImplementedError,
3872 "GetFinalPathNameByHandle not available on this platform");
3873 }
3874
3875 hFile = CreateFileW(
3876 path,
3877 0, /* desired access */
3878 0, /* share mode */
3879 NULL, /* security attributes */
3880 OPEN_EXISTING,
3881 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3882 FILE_FLAG_BACKUP_SEMANTICS,
3883 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003884
Victor Stinnereb5657a2011-09-30 01:44:27 +02003885 if(hFile == INVALID_HANDLE_VALUE)
3886 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003887
3888 /* We have a good handle to the target, use it to determine the
3889 target path name. */
3890 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3891
3892 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003893 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003894
3895 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3896 if(!target_path)
3897 return PyErr_NoMemory();
3898
3899 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3900 buf_size, VOLUME_NAME_DOS);
3901 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003902 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003903
3904 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003905 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003906
3907 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003908 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003909 free(target_path);
3910 return result;
3911
3912} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003913
3914static PyObject *
3915posix__getfileinformation(PyObject *self, PyObject *args)
3916{
3917 HANDLE hFile;
3918 BY_HANDLE_FILE_INFORMATION info;
3919 int fd;
3920
3921 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3922 return NULL;
3923
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003924 if (!_PyVerify_fd(fd))
3925 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003926
3927 hFile = (HANDLE)_get_osfhandle(fd);
3928 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003929 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003930
3931 if (!GetFileInformationByHandle(hFile, &info))
3932 return win32_error("_getfileinformation", NULL);
3933
3934 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3935 info.nFileIndexHigh,
3936 info.nFileIndexLow);
3937}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003938
Brian Curtin95d028f2011-06-09 09:10:38 -05003939PyDoc_STRVAR(posix__isdir__doc__,
3940"Return true if the pathname refers to an existing directory.");
3941
Brian Curtin9c669cc2011-06-08 18:17:18 -05003942static PyObject *
3943posix__isdir(PyObject *self, PyObject *args)
3944{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003945 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003946 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003947 DWORD attributes;
3948
3949 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003950 wchar_t *wpath = PyUnicode_AsUnicode(po);
3951 if (wpath == NULL)
3952 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003953
3954 attributes = GetFileAttributesW(wpath);
3955 if (attributes == INVALID_FILE_ATTRIBUTES)
3956 Py_RETURN_FALSE;
3957 goto check;
3958 }
3959 /* Drop the argument parsing error as narrow strings
3960 are also valid. */
3961 PyErr_Clear();
3962
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003963 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003964 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003965 if (win32_warn_bytes_api())
3966 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003967 attributes = GetFileAttributesA(path);
3968 if (attributes == INVALID_FILE_ATTRIBUTES)
3969 Py_RETURN_FALSE;
3970
3971check:
3972 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3973 Py_RETURN_TRUE;
3974 else
3975 Py_RETURN_FALSE;
3976}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003977#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003978
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003979PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003980"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3981Create a directory.\n\
3982\n\
3983If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3984 and path should be relative; path will then be relative to that directory.\n\
3985dir_fd may not be implemented on your platform.\n\
3986 If it is unavailable, using it will raise a NotImplementedError.\n\
3987\n\
3988The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003989
Barry Warsaw53699e91996-12-10 23:23:01 +00003990static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003991posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003992{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003994 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995 int dir_fd = DEFAULT_DIR_FD;
3996 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3997 PyObject *return_value = NULL;
3998 int result;
3999
4000 memset(&path, 0, sizeof(path));
4001 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4002 path_converter, &path, &mode,
4003#ifdef HAVE_MKDIRAT
4004 dir_fd_converter, &dir_fd
4005#else
4006 dir_fd_unavailable, &dir_fd
4007#endif
4008 ))
4009 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004010
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004011#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013 if (path.wide)
4014 result = CreateDirectoryW(path.wide, NULL);
4015 else
4016 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004018
Larry Hastings9cf065c2012-06-22 16:30:09 -07004019 if (!result) {
4020 return_value = win32_error_object("mkdir", path.object);
4021 goto exit;
4022 }
4023#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004025#if HAVE_MKDIRAT
4026 if (dir_fd != DEFAULT_DIR_FD)
4027 result = mkdirat(dir_fd, path.narrow, mode);
4028 else
4029#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004030#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004031 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004032#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004033 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004034#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004035 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004036 if (result < 0) {
4037 return_value = path_error("mkdir", &path);
4038 goto exit;
4039 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004040#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004041 return_value = Py_None;
4042 Py_INCREF(Py_None);
4043exit:
4044 path_cleanup(&path);
4045 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004046}
4047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004048
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004049/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4050#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004051#include <sys/resource.h>
4052#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004053
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004054
4055#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004057"nice(inc) -> new_priority\n\n\
4058Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004059
Barry Warsaw53699e91996-12-10 23:23:01 +00004060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004061posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004062{
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004064
Victor Stinner8c62be82010-05-06 00:08:46 +00004065 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4066 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004067
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 /* There are two flavours of 'nice': one that returns the new
4069 priority (as required by almost all standards out there) and the
4070 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4071 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004072
Victor Stinner8c62be82010-05-06 00:08:46 +00004073 If we are of the nice family that returns the new priority, we
4074 need to clear errno before the call, and check if errno is filled
4075 before calling posix_error() on a returnvalue of -1, because the
4076 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004077
Victor Stinner8c62be82010-05-06 00:08:46 +00004078 errno = 0;
4079 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004080#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004081 if (value == 0)
4082 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004083#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004084 if (value == -1 && errno != 0)
4085 /* either nice() or getpriority() returned an error */
4086 return posix_error();
4087 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004088}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004089#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004090
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004091
4092#ifdef HAVE_GETPRIORITY
4093PyDoc_STRVAR(posix_getpriority__doc__,
4094"getpriority(which, who) -> current_priority\n\n\
4095Get program scheduling priority.");
4096
4097static PyObject *
4098posix_getpriority(PyObject *self, PyObject *args)
4099{
4100 int which, who, retval;
4101
4102 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4103 return NULL;
4104 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004105 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004106 if (errno != 0)
4107 return posix_error();
4108 return PyLong_FromLong((long)retval);
4109}
4110#endif /* HAVE_GETPRIORITY */
4111
4112
4113#ifdef HAVE_SETPRIORITY
4114PyDoc_STRVAR(posix_setpriority__doc__,
4115"setpriority(which, who, prio) -> None\n\n\
4116Set program scheduling priority.");
4117
4118static PyObject *
4119posix_setpriority(PyObject *self, PyObject *args)
4120{
4121 int which, who, prio, retval;
4122
4123 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4124 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004125 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004126 if (retval == -1)
4127 return posix_error();
4128 Py_RETURN_NONE;
4129}
4130#endif /* HAVE_SETPRIORITY */
4131
4132
Barry Warsaw53699e91996-12-10 23:23:01 +00004133static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004135{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136 char *function_name = is_replace ? "replace" : "rename";
4137 path_t src;
4138 path_t dst;
4139 int src_dir_fd = DEFAULT_DIR_FD;
4140 int dst_dir_fd = DEFAULT_DIR_FD;
4141 int dir_fd_specified;
4142 PyObject *return_value = NULL;
4143 char format[24];
4144 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4145
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004146#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004147 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004148 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004149#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004150 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004151#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004152
4153 memset(&src, 0, sizeof(src));
4154 memset(&dst, 0, sizeof(dst));
4155 strcpy(format, "O&O&|$O&O&:");
4156 strcat(format, function_name);
4157 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4158 path_converter, &src,
4159 path_converter, &dst,
4160 dir_fd_converter, &src_dir_fd,
4161 dir_fd_converter, &dst_dir_fd))
4162 return NULL;
4163
4164 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4165 (dst_dir_fd != DEFAULT_DIR_FD);
4166#ifndef HAVE_RENAMEAT
4167 if (dir_fd_specified) {
4168 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4169 goto exit;
4170 }
4171#endif
4172
4173 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4174 PyErr_Format(PyExc_ValueError,
4175 "%s: src and dst must be the same type", function_name);
4176 goto exit;
4177 }
4178
4179#ifdef MS_WINDOWS
4180 Py_BEGIN_ALLOW_THREADS
4181 if (src.wide)
4182 result = MoveFileExW(src.wide, dst.wide, flags);
4183 else
4184 result = MoveFileExA(src.narrow, dst.narrow, flags);
4185 Py_END_ALLOW_THREADS
4186
4187 if (!result) {
4188 return_value = win32_error_object(function_name, dst.object);
4189 goto exit;
4190 }
4191
4192#else
4193 Py_BEGIN_ALLOW_THREADS
4194#ifdef HAVE_RENAMEAT
4195 if (dir_fd_specified)
4196 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4197 else
4198#endif
4199 result = rename(src.narrow, dst.narrow);
4200 Py_END_ALLOW_THREADS
4201
4202 if (result) {
4203 return_value = path_error(function_name, &dst);
4204 goto exit;
4205 }
4206#endif
4207
4208 Py_INCREF(Py_None);
4209 return_value = Py_None;
4210exit:
4211 path_cleanup(&src);
4212 path_cleanup(&dst);
4213 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004214}
4215
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004216PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004217"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4218Rename a file or directory.\n\
4219\n\
4220If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4221 descriptor open to a directory, and the respective path string (src or dst)\n\
4222 should be relative; the path will then be relative to that directory.\n\
4223src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4224 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004225
4226static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004227posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004228{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004229 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004230}
4231
4232PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004233"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4234Rename a file or directory, overwriting the destination.\n\
4235\n\
4236If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4237 descriptor open to a directory, and the respective path string (src or dst)\n\
4238 should be relative; the path will then be relative to that directory.\n\
4239src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4240 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004241
4242static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004243posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004244{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004245 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004246}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004248PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004249"rmdir(path, *, dir_fd=None)\n\n\
4250Remove a directory.\n\
4251\n\
4252If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4253 and path should be relative; path will then be relative to that directory.\n\
4254dir_fd may not be implemented on your platform.\n\
4255 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004256
Barry Warsaw53699e91996-12-10 23:23:01 +00004257static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004258posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004259{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004260 path_t path;
4261 int dir_fd = DEFAULT_DIR_FD;
4262 static char *keywords[] = {"path", "dir_fd", NULL};
4263 int result;
4264 PyObject *return_value = NULL;
4265
4266 memset(&path, 0, sizeof(path));
4267 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4268 path_converter, &path,
4269#ifdef HAVE_UNLINKAT
4270 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004271#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004272 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004273#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004274 ))
4275 return NULL;
4276
4277 Py_BEGIN_ALLOW_THREADS
4278#ifdef MS_WINDOWS
4279 if (path.wide)
4280 result = RemoveDirectoryW(path.wide);
4281 else
4282 result = RemoveDirectoryA(path.narrow);
4283 result = !result; /* Windows, success=1, UNIX, success=0 */
4284#else
4285#ifdef HAVE_UNLINKAT
4286 if (dir_fd != DEFAULT_DIR_FD)
4287 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4288 else
4289#endif
4290 result = rmdir(path.narrow);
4291#endif
4292 Py_END_ALLOW_THREADS
4293
4294 if (result) {
4295 return_value = path_error("rmdir", &path);
4296 goto exit;
4297 }
4298
4299 return_value = Py_None;
4300 Py_INCREF(Py_None);
4301
4302exit:
4303 path_cleanup(&path);
4304 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004305}
4306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004307
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004308#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004309PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004310"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004311Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004312
Barry Warsaw53699e91996-12-10 23:23:01 +00004313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004314posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004315{
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004317#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004318 wchar_t *command;
4319 if (!PyArg_ParseTuple(args, "u:system", &command))
4320 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004321
Victor Stinner8c62be82010-05-06 00:08:46 +00004322 Py_BEGIN_ALLOW_THREADS
4323 sts = _wsystem(command);
4324 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004325#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004326 PyObject *command_obj;
4327 char *command;
4328 if (!PyArg_ParseTuple(args, "O&:system",
4329 PyUnicode_FSConverter, &command_obj))
4330 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004331
Victor Stinner8c62be82010-05-06 00:08:46 +00004332 command = PyBytes_AsString(command_obj);
4333 Py_BEGIN_ALLOW_THREADS
4334 sts = system(command);
4335 Py_END_ALLOW_THREADS
4336 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004337#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004338 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004339}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004340#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004342
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004343PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004344"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004345Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004346
Barry Warsaw53699e91996-12-10 23:23:01 +00004347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004348posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004349{
Victor Stinner8c62be82010-05-06 00:08:46 +00004350 int i;
4351 if (!PyArg_ParseTuple(args, "i:umask", &i))
4352 return NULL;
4353 i = (int)umask(i);
4354 if (i < 0)
4355 return posix_error();
4356 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004357}
4358
Brian Curtind40e6f72010-07-08 21:39:08 +00004359#ifdef MS_WINDOWS
4360
4361/* override the default DeleteFileW behavior so that directory
4362symlinks can be removed with this function, the same as with
4363Unix symlinks */
4364BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4365{
4366 WIN32_FILE_ATTRIBUTE_DATA info;
4367 WIN32_FIND_DATAW find_data;
4368 HANDLE find_data_handle;
4369 int is_directory = 0;
4370 int is_link = 0;
4371
4372 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4373 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004374
Brian Curtind40e6f72010-07-08 21:39:08 +00004375 /* Get WIN32_FIND_DATA structure for the path to determine if
4376 it is a symlink */
4377 if(is_directory &&
4378 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4379 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4380
4381 if(find_data_handle != INVALID_HANDLE_VALUE) {
4382 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4383 FindClose(find_data_handle);
4384 }
4385 }
4386 }
4387
4388 if (is_directory && is_link)
4389 return RemoveDirectoryW(lpFileName);
4390
4391 return DeleteFileW(lpFileName);
4392}
4393#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004395PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004396"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397Remove a file (same as remove()).\n\
4398\n\
4399If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4400 and path should be relative; path will then be relative to that directory.\n\
4401dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004402 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004403
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004404PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004405"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004406Remove a file (same as unlink()).\n\
4407\n\
4408If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4409 and path should be relative; path will then be relative to that directory.\n\
4410dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004411 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
Barry Warsaw53699e91996-12-10 23:23:01 +00004413static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004414posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004415{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004416 path_t path;
4417 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004418 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004419 int result;
4420 PyObject *return_value = NULL;
4421
4422 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004423 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004424 path_converter, &path,
4425#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004426 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004427#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004428 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004429#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004430 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004431 return NULL;
4432
4433 Py_BEGIN_ALLOW_THREADS
4434#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004435 if (path.wide)
4436 result = Py_DeleteFileW(path.wide);
4437 else
4438 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439 result = !result; /* Windows, success=1, UNIX, success=0 */
4440#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004441#ifdef HAVE_UNLINKAT
4442 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004443 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 else
4445#endif /* HAVE_UNLINKAT */
4446 result = unlink(path.narrow);
4447#endif
4448 Py_END_ALLOW_THREADS
4449
4450 if (result) {
4451 return_value = path_error("unlink", &path);
4452 goto exit;
4453 }
4454
4455 return_value = Py_None;
4456 Py_INCREF(Py_None);
4457
4458exit:
4459 path_cleanup(&path);
4460 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004461}
4462
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004464PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004465"uname() -> uname_result\n\n\
4466Return an object identifying the current operating system.\n\
4467The object behaves like a named tuple with the following fields:\n\
4468 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004469
Larry Hastings605a62d2012-06-24 04:33:36 -07004470static PyStructSequence_Field uname_result_fields[] = {
4471 {"sysname", "operating system name"},
4472 {"nodename", "name of machine on network (implementation-defined)"},
4473 {"release", "operating system release"},
4474 {"version", "operating system version"},
4475 {"machine", "hardware identifier"},
4476 {NULL}
4477};
4478
4479PyDoc_STRVAR(uname_result__doc__,
4480"uname_result: Result from os.uname().\n\n\
4481This object may be accessed either as a tuple of\n\
4482 (sysname, nodename, release, version, machine),\n\
4483or via the attributes sysname, nodename, release, version, and machine.\n\
4484\n\
4485See os.uname for more information.");
4486
4487static PyStructSequence_Desc uname_result_desc = {
4488 "uname_result", /* name */
4489 uname_result__doc__, /* doc */
4490 uname_result_fields,
4491 5
4492};
4493
4494static PyTypeObject UnameResultType;
4495
4496
4497#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004498static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004499posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004500{
Victor Stinner8c62be82010-05-06 00:08:46 +00004501 struct utsname u;
4502 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004503 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004504
Victor Stinner8c62be82010-05-06 00:08:46 +00004505 Py_BEGIN_ALLOW_THREADS
4506 res = uname(&u);
4507 Py_END_ALLOW_THREADS
4508 if (res < 0)
4509 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004510
4511 value = PyStructSequence_New(&UnameResultType);
4512 if (value == NULL)
4513 return NULL;
4514
4515#define SET(i, field) \
4516 { \
4517 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4518 if (!o) { \
4519 Py_DECREF(value); \
4520 return NULL; \
4521 } \
4522 PyStructSequence_SET_ITEM(value, i, o); \
4523 } \
4524
4525 SET(0, u.sysname);
4526 SET(1, u.nodename);
4527 SET(2, u.release);
4528 SET(3, u.version);
4529 SET(4, u.machine);
4530
4531#undef SET
4532
4533 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004534}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004535#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004536
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004537
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538PyDoc_STRVAR(posix_utime__doc__,
4539"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4540Set the access and modified time of path.\n\
4541\n\
4542path may always be specified as a string.\n\
4543On some platforms, path may also be specified as an open file descriptor.\n\
4544 If this functionality is unavailable, using it raises an exception.\n\
4545\n\
4546If times is not None, it must be a tuple (atime, mtime);\n\
4547 atime and mtime should be expressed as float seconds since the epoch.\n\
4548If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4549 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4550 since the epoch.\n\
4551If both times and ns are None, utime uses the current time.\n\
4552Specifying tuples for both times and ns is an error.\n\
4553\n\
4554If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4555 and path should be relative; path will then be relative to that directory.\n\
4556If follow_symlinks is False, and the last element of the path is a symbolic\n\
4557 link, utime will modify the symbolic link itself instead of the file the\n\
4558 link points to.\n\
4559It is an error to use dir_fd or follow_symlinks when specifying path\n\
4560 as an open file descriptor.\n\
4561dir_fd and follow_symlinks may not be available on your platform.\n\
4562 If they are unavailable, using them will raise a NotImplementedError.");
4563
4564typedef struct {
4565 int now;
4566 time_t atime_s;
4567 long atime_ns;
4568 time_t mtime_s;
4569 long mtime_ns;
4570} utime_t;
4571
4572/*
4573 * these macros assume that "utime" is a pointer to a utime_t
4574 * they also intentionally leak the declaration of a pointer named "time"
4575 */
4576#define UTIME_TO_TIMESPEC \
4577 struct timespec ts[2]; \
4578 struct timespec *time; \
4579 if (utime->now) \
4580 time = NULL; \
4581 else { \
4582 ts[0].tv_sec = utime->atime_s; \
4583 ts[0].tv_nsec = utime->atime_ns; \
4584 ts[1].tv_sec = utime->mtime_s; \
4585 ts[1].tv_nsec = utime->mtime_ns; \
4586 time = ts; \
4587 } \
4588
4589#define UTIME_TO_TIMEVAL \
4590 struct timeval tv[2]; \
4591 struct timeval *time; \
4592 if (utime->now) \
4593 time = NULL; \
4594 else { \
4595 tv[0].tv_sec = utime->atime_s; \
4596 tv[0].tv_usec = utime->atime_ns / 1000; \
4597 tv[1].tv_sec = utime->mtime_s; \
4598 tv[1].tv_usec = utime->mtime_ns / 1000; \
4599 time = tv; \
4600 } \
4601
4602#define UTIME_TO_UTIMBUF \
4603 struct utimbuf u[2]; \
4604 struct utimbuf *time; \
4605 if (utime->now) \
4606 time = NULL; \
4607 else { \
4608 u.actime = utime->atime_s; \
4609 u.modtime = utime->mtime_s; \
4610 time = u; \
4611 }
4612
4613#define UTIME_TO_TIME_T \
4614 time_t timet[2]; \
4615 struct timet time; \
4616 if (utime->now) \
4617 time = NULL; \
4618 else { \
4619 timet[0] = utime->atime_s; \
4620 timet[1] = utime->mtime_s; \
4621 time = &timet; \
4622 } \
4623
4624
4625#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4626
4627#if UTIME_HAVE_DIR_FD
4628
4629static int
4630utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4631{
4632#ifdef HAVE_UTIMENSAT
4633 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4634 UTIME_TO_TIMESPEC;
4635 return utimensat(dir_fd, path, time, flags);
4636#elif defined(HAVE_FUTIMESAT)
4637 UTIME_TO_TIMEVAL;
4638 /*
4639 * follow_symlinks will never be false here;
4640 * we only allow !follow_symlinks and dir_fd together
4641 * if we have utimensat()
4642 */
4643 assert(follow_symlinks);
4644 return futimesat(dir_fd, path, time);
4645#endif
4646}
4647
4648#endif
4649
4650#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4651
4652#if UTIME_HAVE_FD
4653
4654static int
4655utime_fd(utime_t *utime, int fd)
4656{
4657#ifdef HAVE_FUTIMENS
4658 UTIME_TO_TIMESPEC;
4659 return futimens(fd, time);
4660#else
4661 UTIME_TO_TIMEVAL;
4662 return futimes(fd, time);
4663#endif
4664}
4665
4666#endif
4667
4668
4669#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4670 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4671
4672#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4673
4674static int
4675utime_nofollow_symlinks(utime_t *utime, char *path)
4676{
4677#ifdef HAVE_UTIMENSAT
4678 UTIME_TO_TIMESPEC;
4679 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4680#else
4681 UTIME_TO_TIMEVAL;
4682 return lutimes(path, time);
4683#endif
4684}
4685
4686#endif
4687
4688#ifndef MS_WINDOWS
4689
4690static int
4691utime_default(utime_t *utime, char *path)
4692{
4693#ifdef HAVE_UTIMENSAT
4694 UTIME_TO_TIMESPEC;
4695 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4696#elif defined(HAVE_UTIMES)
4697 UTIME_TO_TIMEVAL;
4698 return utimes(path, time);
4699#elif defined(HAVE_UTIME_H)
4700 UTIME_TO_UTIMBUF;
4701 return utime(path, time);
4702#else
4703 UTIME_TO_TIME_T;
4704 return utime(path, time);
4705#endif
4706}
4707
4708#endif
4709
Larry Hastings76ad59b2012-05-03 00:30:07 -07004710static int
4711split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4712{
4713 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004714 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004715 divmod = PyNumber_Divmod(py_long, billion);
4716 if (!divmod)
4717 goto exit;
4718 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4719 if ((*s == -1) && PyErr_Occurred())
4720 goto exit;
4721 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004722 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004723 goto exit;
4724
4725 result = 1;
4726exit:
4727 Py_XDECREF(divmod);
4728 return result;
4729}
4730
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731static PyObject *
4732posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004733{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004735 PyObject *times = NULL;
4736 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737 int dir_fd = DEFAULT_DIR_FD;
4738 int follow_symlinks = 1;
4739 char *keywords[] = {"path", "times", "ns", "dir_fd",
4740 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004741
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004743
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744#ifdef MS_WINDOWS
4745 HANDLE hFile;
4746 FILETIME atime, mtime;
4747#else
4748 int result;
4749#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004750
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004752
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 memset(&path, 0, sizeof(path));
4754#if UTIME_HAVE_FD
4755 path.allow_fd = 1;
4756#endif
4757 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4758 "O&|O$OO&p:utime", keywords,
4759 path_converter, &path,
4760 &times, &ns,
4761#if UTIME_HAVE_DIR_FD
4762 dir_fd_converter, &dir_fd,
4763#else
4764 dir_fd_unavailable, &dir_fd,
4765#endif
4766 &follow_symlinks
4767 ))
4768 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004769
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 if (times && (times != Py_None) && ns) {
4771 PyErr_SetString(PyExc_ValueError,
4772 "utime: you may specify either 'times'"
4773 " or 'ns' but not both");
4774 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004775 }
4776
4777 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004778 time_t a_sec, m_sec;
4779 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004780 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004781 PyErr_SetString(PyExc_TypeError,
4782 "utime: 'times' must be either"
4783 " a tuple of two ints or None");
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 (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004788 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004789 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004790 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004792 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004793 utime.atime_s = a_sec;
4794 utime.atime_ns = a_nsec;
4795 utime.mtime_s = m_sec;
4796 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004797 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004798 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004799 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004800 PyErr_SetString(PyExc_TypeError,
4801 "utime: 'ns' must be a tuple of two ints");
4802 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004803 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004805 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004806 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004807 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808 &utime.mtime_s, &utime.mtime_ns)) {
4809 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004810 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 }
4812 else {
4813 /* times and ns are both None/unspecified. use "now". */
4814 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004815 }
4816
Larry Hastings9cf065c2012-06-22 16:30:09 -07004817#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4818 if (follow_symlinks_specified("utime", follow_symlinks))
4819 goto exit;
4820#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004821
Larry Hastings9cf065c2012-06-22 16:30:09 -07004822 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4823 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4824 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4825 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004826
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827#if !defined(HAVE_UTIMENSAT)
4828 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004829 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830 "utime: cannot use dir_fd and follow_symlinks "
4831 "together on this platform");
4832 goto exit;
4833 }
4834#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004835
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004836#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004837 Py_BEGIN_ALLOW_THREADS
4838 if (path.wide)
4839 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004840 NULL, OPEN_EXISTING,
4841 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842 else
4843 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004844 NULL, OPEN_EXISTING,
4845 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004846 Py_END_ALLOW_THREADS
4847 if (hFile == INVALID_HANDLE_VALUE) {
4848 win32_error_object("utime", path.object);
4849 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004850 }
4851
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004853 SYSTEMTIME now;
4854 GetSystemTime(&now);
4855 if (!SystemTimeToFileTime(&now, &mtime) ||
4856 !SystemTimeToFileTime(&now, &atime)) {
4857 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004859 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004860 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4863 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004864 }
4865 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4866 /* Avoid putting the file name into the error here,
4867 as that may confuse the user into believing that
4868 something is wrong with the file, when it also
4869 could be the time stamp that gives a problem. */
4870 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004871 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004873#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004874 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004875
Larry Hastings9cf065c2012-06-22 16:30:09 -07004876#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4877 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4878 result = utime_nofollow_symlinks(&utime, path.narrow);
4879 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004880#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004881
4882#if UTIME_HAVE_DIR_FD
4883 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4884 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4885 else
4886#endif
4887
4888#if UTIME_HAVE_FD
4889 if (path.fd != -1)
4890 result = utime_fd(&utime, path.fd);
4891 else
4892#endif
4893
4894 result = utime_default(&utime, path.narrow);
4895
4896 Py_END_ALLOW_THREADS
4897
4898 if (result < 0) {
4899 /* see previous comment about not putting filename in error here */
4900 return_value = posix_error();
4901 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004903
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004904#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004905
4906 Py_INCREF(Py_None);
4907 return_value = Py_None;
4908
4909exit:
4910 path_cleanup(&path);
4911#ifdef MS_WINDOWS
4912 if (hFile != INVALID_HANDLE_VALUE)
4913 CloseHandle(hFile);
4914#endif
4915 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004916}
4917
Guido van Rossum3b066191991-06-04 19:40:25 +00004918/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004919
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004920PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004921"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004922Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004923
Barry Warsaw53699e91996-12-10 23:23:01 +00004924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004925posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004926{
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 int sts;
4928 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4929 return NULL;
4930 _exit(sts);
4931 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004932}
4933
Martin v. Löwis114619e2002-10-07 06:44:21 +00004934#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4935static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004936free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004937{
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 Py_ssize_t i;
4939 for (i = 0; i < count; i++)
4940 PyMem_Free(array[i]);
4941 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004942}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004943
Antoine Pitrou69f71142009-05-24 21:25:49 +00004944static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004945int fsconvert_strdup(PyObject *o, char**out)
4946{
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 PyObject *bytes;
4948 Py_ssize_t size;
4949 if (!PyUnicode_FSConverter(o, &bytes))
4950 return 0;
4951 size = PyBytes_GET_SIZE(bytes);
4952 *out = PyMem_Malloc(size+1);
4953 if (!*out)
4954 return 0;
4955 memcpy(*out, PyBytes_AsString(bytes), size+1);
4956 Py_DECREF(bytes);
4957 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004958}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004959#endif
4960
Ross Lagerwall7807c352011-03-17 20:20:30 +02004961#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004962static char**
4963parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4964{
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 char **envlist;
4966 Py_ssize_t i, pos, envc;
4967 PyObject *keys=NULL, *vals=NULL;
4968 PyObject *key, *val, *key2, *val2;
4969 char *p, *k, *v;
4970 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004971
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 i = PyMapping_Size(env);
4973 if (i < 0)
4974 return NULL;
4975 envlist = PyMem_NEW(char *, i + 1);
4976 if (envlist == NULL) {
4977 PyErr_NoMemory();
4978 return NULL;
4979 }
4980 envc = 0;
4981 keys = PyMapping_Keys(env);
4982 vals = PyMapping_Values(env);
4983 if (!keys || !vals)
4984 goto error;
4985 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4986 PyErr_Format(PyExc_TypeError,
4987 "env.keys() or env.values() is not a list");
4988 goto error;
4989 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004990
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 for (pos = 0; pos < i; pos++) {
4992 key = PyList_GetItem(keys, pos);
4993 val = PyList_GetItem(vals, pos);
4994 if (!key || !val)
4995 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004996
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 if (PyUnicode_FSConverter(key, &key2) == 0)
4998 goto error;
4999 if (PyUnicode_FSConverter(val, &val2) == 0) {
5000 Py_DECREF(key2);
5001 goto error;
5002 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005003
5004#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
5006 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00005007#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005008 k = PyBytes_AsString(key2);
5009 v = PyBytes_AsString(val2);
5010 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005011
Victor Stinner8c62be82010-05-06 00:08:46 +00005012 p = PyMem_NEW(char, len);
5013 if (p == NULL) {
5014 PyErr_NoMemory();
5015 Py_DECREF(key2);
5016 Py_DECREF(val2);
5017 goto error;
5018 }
5019 PyOS_snprintf(p, len, "%s=%s", k, v);
5020 envlist[envc++] = p;
5021 Py_DECREF(key2);
5022 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005023#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005025#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005026 }
5027 Py_DECREF(vals);
5028 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005029
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 envlist[envc] = 0;
5031 *envc_ptr = envc;
5032 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005033
5034error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005035 Py_XDECREF(keys);
5036 Py_XDECREF(vals);
5037 while (--envc >= 0)
5038 PyMem_DEL(envlist[envc]);
5039 PyMem_DEL(envlist);
5040 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005041}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005042
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043static char**
5044parse_arglist(PyObject* argv, Py_ssize_t *argc)
5045{
5046 int i;
5047 char **argvlist = PyMem_NEW(char *, *argc+1);
5048 if (argvlist == NULL) {
5049 PyErr_NoMemory();
5050 return NULL;
5051 }
5052 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005053 PyObject* item = PySequence_ITEM(argv, i);
5054 if (item == NULL)
5055 goto fail;
5056 if (!fsconvert_strdup(item, &argvlist[i])) {
5057 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005058 goto fail;
5059 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005060 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 }
5062 argvlist[*argc] = NULL;
5063 return argvlist;
5064fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005065 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 free_string_array(argvlist, *argc);
5067 return NULL;
5068}
5069#endif
5070
5071#ifdef HAVE_EXECV
5072PyDoc_STRVAR(posix_execv__doc__,
5073"execv(path, args)\n\n\
5074Execute an executable path with arguments, replacing current process.\n\
5075\n\
5076 path: path of executable file\n\
5077 args: tuple or list of strings");
5078
5079static PyObject *
5080posix_execv(PyObject *self, PyObject *args)
5081{
5082 PyObject *opath;
5083 char *path;
5084 PyObject *argv;
5085 char **argvlist;
5086 Py_ssize_t argc;
5087
5088 /* execv has two arguments: (path, argv), where
5089 argv is a list or tuple of strings. */
5090
5091 if (!PyArg_ParseTuple(args, "O&O:execv",
5092 PyUnicode_FSConverter,
5093 &opath, &argv))
5094 return NULL;
5095 path = PyBytes_AsString(opath);
5096 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5097 PyErr_SetString(PyExc_TypeError,
5098 "execv() arg 2 must be a tuple or list");
5099 Py_DECREF(opath);
5100 return NULL;
5101 }
5102 argc = PySequence_Size(argv);
5103 if (argc < 1) {
5104 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5105 Py_DECREF(opath);
5106 return NULL;
5107 }
5108
5109 argvlist = parse_arglist(argv, &argc);
5110 if (argvlist == NULL) {
5111 Py_DECREF(opath);
5112 return NULL;
5113 }
5114
5115 execv(path, argvlist);
5116
5117 /* If we get here it's definitely an error */
5118
5119 free_string_array(argvlist, argc);
5120 Py_DECREF(opath);
5121 return posix_error();
5122}
5123
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005124PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005125"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005126Execute a path with arguments and environment, replacing current process.\n\
5127\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 path: path of executable file\n\
5129 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005130 env: dictionary of strings mapping to strings\n\
5131\n\
5132On some platforms, you may specify an open file descriptor for path;\n\
5133 execve will execute the program the file descriptor is open to.\n\
5134 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005135
Barry Warsaw53699e91996-12-10 23:23:01 +00005136static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005137posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005138{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005139 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005141 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005142 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005143 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005144 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005145
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 /* execve has three arguments: (path, argv, env), where
5147 argv is a list or tuple of strings and env is a dictionary
5148 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005149
Larry Hastings9cf065c2012-06-22 16:30:09 -07005150 memset(&path, 0, sizeof(path));
5151#ifdef HAVE_FEXECVE
5152 path.allow_fd = 1;
5153#endif
5154 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5155 path_converter, &path,
5156 &argv, &env
5157 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005159
Ross Lagerwall7807c352011-03-17 20:20:30 +02005160 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005162 "execve: argv must be a tuple or list");
5163 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005165 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 if (!PyMapping_Check(env)) {
5167 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005168 "execve: environment must be a mapping object");
5169 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005171
Ross Lagerwall7807c352011-03-17 20:20:30 +02005172 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005174 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005176
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 envlist = parse_envlist(env, &envc);
5178 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005179 goto fail;
5180
Larry Hastings9cf065c2012-06-22 16:30:09 -07005181#ifdef HAVE_FEXECVE
5182 if (path.fd > -1)
5183 fexecve(path.fd, argvlist, envlist);
5184 else
5185#endif
5186 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005187
5188 /* If we get here it's definitely an error */
5189
Larry Hastings9cf065c2012-06-22 16:30:09 -07005190 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005191
5192 while (--envc >= 0)
5193 PyMem_DEL(envlist[envc]);
5194 PyMem_DEL(envlist);
5195 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005196 if (argvlist)
5197 free_string_array(argvlist, argc);
5198 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005199 return NULL;
5200}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005201#endif /* HAVE_EXECV */
5202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005203
Guido van Rossuma1065681999-01-25 23:20:23 +00005204#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005205PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005206"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005207Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005208\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 mode: mode of process creation\n\
5210 path: path of executable file\n\
5211 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005212
5213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005214posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005215{
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 PyObject *opath;
5217 char *path;
5218 PyObject *argv;
5219 char **argvlist;
5220 int mode, i;
5221 Py_ssize_t argc;
5222 Py_intptr_t spawnval;
5223 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005224
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 /* spawnv has three arguments: (mode, path, argv), where
5226 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005227
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5229 PyUnicode_FSConverter,
5230 &opath, &argv))
5231 return NULL;
5232 path = PyBytes_AsString(opath);
5233 if (PyList_Check(argv)) {
5234 argc = PyList_Size(argv);
5235 getitem = PyList_GetItem;
5236 }
5237 else if (PyTuple_Check(argv)) {
5238 argc = PyTuple_Size(argv);
5239 getitem = PyTuple_GetItem;
5240 }
5241 else {
5242 PyErr_SetString(PyExc_TypeError,
5243 "spawnv() arg 2 must be a tuple or list");
5244 Py_DECREF(opath);
5245 return NULL;
5246 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005247
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 argvlist = PyMem_NEW(char *, argc+1);
5249 if (argvlist == NULL) {
5250 Py_DECREF(opath);
5251 return PyErr_NoMemory();
5252 }
5253 for (i = 0; i < argc; i++) {
5254 if (!fsconvert_strdup((*getitem)(argv, i),
5255 &argvlist[i])) {
5256 free_string_array(argvlist, i);
5257 PyErr_SetString(
5258 PyExc_TypeError,
5259 "spawnv() arg 2 must contain only strings");
5260 Py_DECREF(opath);
5261 return NULL;
5262 }
5263 }
5264 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005265
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005266#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 Py_BEGIN_ALLOW_THREADS
5268 spawnval = spawnv(mode, path, argvlist);
5269 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005270#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005271 if (mode == _OLD_P_OVERLAY)
5272 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005273
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 Py_BEGIN_ALLOW_THREADS
5275 spawnval = _spawnv(mode, path, argvlist);
5276 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005277#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005278
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 free_string_array(argvlist, argc);
5280 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005281
Victor Stinner8c62be82010-05-06 00:08:46 +00005282 if (spawnval == -1)
5283 return posix_error();
5284 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005285#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005288 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005289#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005290}
5291
5292
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005293PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005294"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005295Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005296\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 mode: mode of process creation\n\
5298 path: path of executable file\n\
5299 args: tuple or list of arguments\n\
5300 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005301
5302static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005303posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005304{
Victor Stinner8c62be82010-05-06 00:08:46 +00005305 PyObject *opath;
5306 char *path;
5307 PyObject *argv, *env;
5308 char **argvlist;
5309 char **envlist;
5310 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005311 int mode;
5312 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005313 Py_intptr_t spawnval;
5314 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5315 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005316
Victor Stinner8c62be82010-05-06 00:08:46 +00005317 /* spawnve has four arguments: (mode, path, argv, env), where
5318 argv is a list or tuple of strings and env is a dictionary
5319 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005320
Victor Stinner8c62be82010-05-06 00:08:46 +00005321 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5322 PyUnicode_FSConverter,
5323 &opath, &argv, &env))
5324 return NULL;
5325 path = PyBytes_AsString(opath);
5326 if (PyList_Check(argv)) {
5327 argc = PyList_Size(argv);
5328 getitem = PyList_GetItem;
5329 }
5330 else if (PyTuple_Check(argv)) {
5331 argc = PyTuple_Size(argv);
5332 getitem = PyTuple_GetItem;
5333 }
5334 else {
5335 PyErr_SetString(PyExc_TypeError,
5336 "spawnve() arg 2 must be a tuple or list");
5337 goto fail_0;
5338 }
5339 if (!PyMapping_Check(env)) {
5340 PyErr_SetString(PyExc_TypeError,
5341 "spawnve() arg 3 must be a mapping object");
5342 goto fail_0;
5343 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005344
Victor Stinner8c62be82010-05-06 00:08:46 +00005345 argvlist = PyMem_NEW(char *, argc+1);
5346 if (argvlist == NULL) {
5347 PyErr_NoMemory();
5348 goto fail_0;
5349 }
5350 for (i = 0; i < argc; i++) {
5351 if (!fsconvert_strdup((*getitem)(argv, i),
5352 &argvlist[i]))
5353 {
5354 lastarg = i;
5355 goto fail_1;
5356 }
5357 }
5358 lastarg = argc;
5359 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005360
Victor Stinner8c62be82010-05-06 00:08:46 +00005361 envlist = parse_envlist(env, &envc);
5362 if (envlist == NULL)
5363 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005364
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005365#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 Py_BEGIN_ALLOW_THREADS
5367 spawnval = spawnve(mode, path, argvlist, envlist);
5368 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005369#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 if (mode == _OLD_P_OVERLAY)
5371 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005372
Victor Stinner8c62be82010-05-06 00:08:46 +00005373 Py_BEGIN_ALLOW_THREADS
5374 spawnval = _spawnve(mode, path, argvlist, envlist);
5375 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005376#endif
Tim Peters25059d32001-12-07 20:35:43 +00005377
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 if (spawnval == -1)
5379 (void) posix_error();
5380 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005381#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005383#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005384 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005385#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005386
Victor Stinner8c62be82010-05-06 00:08:46 +00005387 while (--envc >= 0)
5388 PyMem_DEL(envlist[envc]);
5389 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005390 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005391 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005392 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 Py_DECREF(opath);
5394 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005395}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005396
5397/* OS/2 supports spawnvp & spawnvpe natively */
5398#if defined(PYOS_OS2)
5399PyDoc_STRVAR(posix_spawnvp__doc__,
5400"spawnvp(mode, file, args)\n\n\
5401Execute the program 'file' in a new process, using the environment\n\
5402search path to find the file.\n\
5403\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005404 mode: mode of process creation\n\
5405 file: executable file name\n\
5406 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005407
5408static PyObject *
5409posix_spawnvp(PyObject *self, PyObject *args)
5410{
Victor Stinner8c62be82010-05-06 00:08:46 +00005411 PyObject *opath;
5412 char *path;
5413 PyObject *argv;
5414 char **argvlist;
5415 int mode, i, argc;
5416 Py_intptr_t spawnval;
5417 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005418
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 /* spawnvp has three arguments: (mode, path, argv), where
5420 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005421
Victor Stinner8c62be82010-05-06 00:08:46 +00005422 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5423 PyUnicode_FSConverter,
5424 &opath, &argv))
5425 return NULL;
5426 path = PyBytes_AsString(opath);
5427 if (PyList_Check(argv)) {
5428 argc = PyList_Size(argv);
5429 getitem = PyList_GetItem;
5430 }
5431 else if (PyTuple_Check(argv)) {
5432 argc = PyTuple_Size(argv);
5433 getitem = PyTuple_GetItem;
5434 }
5435 else {
5436 PyErr_SetString(PyExc_TypeError,
5437 "spawnvp() arg 2 must be a tuple or list");
5438 Py_DECREF(opath);
5439 return NULL;
5440 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005441
Victor Stinner8c62be82010-05-06 00:08:46 +00005442 argvlist = PyMem_NEW(char *, argc+1);
5443 if (argvlist == NULL) {
5444 Py_DECREF(opath);
5445 return PyErr_NoMemory();
5446 }
5447 for (i = 0; i < argc; i++) {
5448 if (!fsconvert_strdup((*getitem)(argv, i),
5449 &argvlist[i])) {
5450 free_string_array(argvlist, i);
5451 PyErr_SetString(
5452 PyExc_TypeError,
5453 "spawnvp() arg 2 must contain only strings");
5454 Py_DECREF(opath);
5455 return NULL;
5456 }
5457 }
5458 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005459
Victor Stinner8c62be82010-05-06 00:08:46 +00005460 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005461#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005462 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005463#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005464 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005465#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005466 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005467
Victor Stinner8c62be82010-05-06 00:08:46 +00005468 free_string_array(argvlist, argc);
5469 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005470
Victor Stinner8c62be82010-05-06 00:08:46 +00005471 if (spawnval == -1)
5472 return posix_error();
5473 else
5474 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005475}
5476
5477
5478PyDoc_STRVAR(posix_spawnvpe__doc__,
5479"spawnvpe(mode, file, args, env)\n\n\
5480Execute the program 'file' in a new process, using the environment\n\
5481search path to find the file.\n\
5482\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005483 mode: mode of process creation\n\
5484 file: executable file name\n\
5485 args: tuple or list of arguments\n\
5486 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005487
5488static PyObject *
5489posix_spawnvpe(PyObject *self, PyObject *args)
5490{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005491 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005492 char *path;
5493 PyObject *argv, *env;
5494 char **argvlist;
5495 char **envlist;
5496 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005497 int mode;
5498 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005499 Py_intptr_t spawnval;
5500 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5501 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005502
Victor Stinner8c62be82010-05-06 00:08:46 +00005503 /* spawnvpe has four arguments: (mode, path, argv, env), where
5504 argv is a list or tuple of strings and env is a dictionary
5505 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005506
Victor Stinner8c62be82010-05-06 00:08:46 +00005507 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5508 PyUnicode_FSConverter,
5509 &opath, &argv, &env))
5510 return NULL;
5511 path = PyBytes_AsString(opath);
5512 if (PyList_Check(argv)) {
5513 argc = PyList_Size(argv);
5514 getitem = PyList_GetItem;
5515 }
5516 else if (PyTuple_Check(argv)) {
5517 argc = PyTuple_Size(argv);
5518 getitem = PyTuple_GetItem;
5519 }
5520 else {
5521 PyErr_SetString(PyExc_TypeError,
5522 "spawnvpe() arg 2 must be a tuple or list");
5523 goto fail_0;
5524 }
5525 if (!PyMapping_Check(env)) {
5526 PyErr_SetString(PyExc_TypeError,
5527 "spawnvpe() arg 3 must be a mapping object");
5528 goto fail_0;
5529 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005530
Victor Stinner8c62be82010-05-06 00:08:46 +00005531 argvlist = PyMem_NEW(char *, argc+1);
5532 if (argvlist == NULL) {
5533 PyErr_NoMemory();
5534 goto fail_0;
5535 }
5536 for (i = 0; i < argc; i++) {
5537 if (!fsconvert_strdup((*getitem)(argv, i),
5538 &argvlist[i]))
5539 {
5540 lastarg = i;
5541 goto fail_1;
5542 }
5543 }
5544 lastarg = argc;
5545 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005546
Victor Stinner8c62be82010-05-06 00:08:46 +00005547 envlist = parse_envlist(env, &envc);
5548 if (envlist == NULL)
5549 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005550
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005552#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005553 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005554#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005556#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005557 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005558
Victor Stinner8c62be82010-05-06 00:08:46 +00005559 if (spawnval == -1)
5560 (void) posix_error();
5561 else
5562 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005563
Victor Stinner8c62be82010-05-06 00:08:46 +00005564 while (--envc >= 0)
5565 PyMem_DEL(envlist[envc]);
5566 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005567 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005568 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005569 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005570 Py_DECREF(opath);
5571 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005572}
5573#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005574#endif /* HAVE_SPAWNV */
5575
5576
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005577#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005578PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005579"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005580Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5581\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005582Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005583
5584static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005585posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005586{
Victor Stinner8c62be82010-05-06 00:08:46 +00005587 pid_t pid;
5588 int result = 0;
5589 _PyImport_AcquireLock();
5590 pid = fork1();
5591 if (pid == 0) {
5592 /* child: this clobbers and resets the import lock. */
5593 PyOS_AfterFork();
5594 } else {
5595 /* parent: release the import lock. */
5596 result = _PyImport_ReleaseLock();
5597 }
5598 if (pid == -1)
5599 return posix_error();
5600 if (result < 0) {
5601 /* Don't clobber the OSError if the fork failed. */
5602 PyErr_SetString(PyExc_RuntimeError,
5603 "not holding the import lock");
5604 return NULL;
5605 }
5606 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005607}
5608#endif
5609
5610
Guido van Rossumad0ee831995-03-01 10:34:45 +00005611#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005613"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005614Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005615Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005616
Barry Warsaw53699e91996-12-10 23:23:01 +00005617static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005618posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005619{
Victor Stinner8c62be82010-05-06 00:08:46 +00005620 pid_t pid;
5621 int result = 0;
5622 _PyImport_AcquireLock();
5623 pid = fork();
5624 if (pid == 0) {
5625 /* child: this clobbers and resets the import lock. */
5626 PyOS_AfterFork();
5627 } else {
5628 /* parent: release the import lock. */
5629 result = _PyImport_ReleaseLock();
5630 }
5631 if (pid == -1)
5632 return posix_error();
5633 if (result < 0) {
5634 /* Don't clobber the OSError if the fork failed. */
5635 PyErr_SetString(PyExc_RuntimeError,
5636 "not holding the import lock");
5637 return NULL;
5638 }
5639 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005640}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005641#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005642
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005643#ifdef HAVE_SCHED_H
5644
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005645#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5646
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005647PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5648"sched_get_priority_max(policy)\n\n\
5649Get the maximum scheduling priority for *policy*.");
5650
5651static PyObject *
5652posix_sched_get_priority_max(PyObject *self, PyObject *args)
5653{
5654 int policy, max;
5655
5656 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5657 return NULL;
5658 max = sched_get_priority_max(policy);
5659 if (max < 0)
5660 return posix_error();
5661 return PyLong_FromLong(max);
5662}
5663
5664PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5665"sched_get_priority_min(policy)\n\n\
5666Get the minimum scheduling priority for *policy*.");
5667
5668static PyObject *
5669posix_sched_get_priority_min(PyObject *self, PyObject *args)
5670{
5671 int policy, min;
5672
5673 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5674 return NULL;
5675 min = sched_get_priority_min(policy);
5676 if (min < 0)
5677 return posix_error();
5678 return PyLong_FromLong(min);
5679}
5680
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005681#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5682
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005683#ifdef HAVE_SCHED_SETSCHEDULER
5684
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005685PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5686"sched_getscheduler(pid)\n\n\
5687Get the scheduling policy for the process with a PID of *pid*.\n\
5688Passing a PID of 0 returns the scheduling policy for the calling process.");
5689
5690static PyObject *
5691posix_sched_getscheduler(PyObject *self, PyObject *args)
5692{
5693 pid_t pid;
5694 int policy;
5695
5696 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5697 return NULL;
5698 policy = sched_getscheduler(pid);
5699 if (policy < 0)
5700 return posix_error();
5701 return PyLong_FromLong(policy);
5702}
5703
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005704#endif
5705
5706#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5707
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005708static PyObject *
5709sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5710{
5711 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005712 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005713
5714 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5715 return NULL;
5716 res = PyStructSequence_New(type);
5717 if (!res)
5718 return NULL;
5719 Py_INCREF(priority);
5720 PyStructSequence_SET_ITEM(res, 0, priority);
5721 return res;
5722}
5723
5724PyDoc_STRVAR(sched_param__doc__,
5725"sched_param(sched_priority): A scheduling parameter.\n\n\
5726Current has only one field: sched_priority");
5727
5728static PyStructSequence_Field sched_param_fields[] = {
5729 {"sched_priority", "the scheduling priority"},
5730 {0}
5731};
5732
5733static PyStructSequence_Desc sched_param_desc = {
5734 "sched_param", /* name */
5735 sched_param__doc__, /* doc */
5736 sched_param_fields,
5737 1
5738};
5739
5740static int
5741convert_sched_param(PyObject *param, struct sched_param *res)
5742{
5743 long priority;
5744
5745 if (Py_TYPE(param) != &SchedParamType) {
5746 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5747 return 0;
5748 }
5749 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5750 if (priority == -1 && PyErr_Occurred())
5751 return 0;
5752 if (priority > INT_MAX || priority < INT_MIN) {
5753 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5754 return 0;
5755 }
5756 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5757 return 1;
5758}
5759
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005760#endif
5761
5762#ifdef HAVE_SCHED_SETSCHEDULER
5763
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005764PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5765"sched_setscheduler(pid, policy, param)\n\n\
5766Set the scheduling policy, *policy*, for *pid*.\n\
5767If *pid* is 0, the calling process is changed.\n\
5768*param* is an instance of sched_param.");
5769
5770static PyObject *
5771posix_sched_setscheduler(PyObject *self, PyObject *args)
5772{
5773 pid_t pid;
5774 int policy;
5775 struct sched_param param;
5776
5777 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5778 &pid, &policy, &convert_sched_param, &param))
5779 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005780
5781 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005782 ** sched_setscheduler() returns 0 in Linux, but the previous
5783 ** scheduling policy under Solaris/Illumos, and others.
5784 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005785 */
5786 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005787 return posix_error();
5788 Py_RETURN_NONE;
5789}
5790
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005791#endif
5792
5793#ifdef HAVE_SCHED_SETPARAM
5794
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005795PyDoc_STRVAR(posix_sched_getparam__doc__,
5796"sched_getparam(pid) -> sched_param\n\n\
5797Returns scheduling parameters for the process with *pid* as an instance of the\n\
5798sched_param class. A PID of 0 means the calling process.");
5799
5800static PyObject *
5801posix_sched_getparam(PyObject *self, PyObject *args)
5802{
5803 pid_t pid;
5804 struct sched_param param;
5805 PyObject *res, *priority;
5806
5807 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5808 return NULL;
5809 if (sched_getparam(pid, &param))
5810 return posix_error();
5811 res = PyStructSequence_New(&SchedParamType);
5812 if (!res)
5813 return NULL;
5814 priority = PyLong_FromLong(param.sched_priority);
5815 if (!priority) {
5816 Py_DECREF(res);
5817 return NULL;
5818 }
5819 PyStructSequence_SET_ITEM(res, 0, priority);
5820 return res;
5821}
5822
5823PyDoc_STRVAR(posix_sched_setparam__doc__,
5824"sched_setparam(pid, param)\n\n\
5825Set scheduling parameters for a process with PID *pid*.\n\
5826A PID of 0 means the calling process.");
5827
5828static PyObject *
5829posix_sched_setparam(PyObject *self, PyObject *args)
5830{
5831 pid_t pid;
5832 struct sched_param param;
5833
5834 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5835 &pid, &convert_sched_param, &param))
5836 return NULL;
5837 if (sched_setparam(pid, &param))
5838 return posix_error();
5839 Py_RETURN_NONE;
5840}
5841
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005842#endif
5843
5844#ifdef HAVE_SCHED_RR_GET_INTERVAL
5845
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005846PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5847"sched_rr_get_interval(pid) -> float\n\n\
5848Return the round-robin quantum for the process with PID *pid* in seconds.");
5849
5850static PyObject *
5851posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5852{
5853 pid_t pid;
5854 struct timespec interval;
5855
5856 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5857 return NULL;
5858 if (sched_rr_get_interval(pid, &interval))
5859 return posix_error();
5860 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5861}
5862
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005863#endif
5864
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005865PyDoc_STRVAR(posix_sched_yield__doc__,
5866"sched_yield()\n\n\
5867Voluntarily relinquish the CPU.");
5868
5869static PyObject *
5870posix_sched_yield(PyObject *self, PyObject *noargs)
5871{
5872 if (sched_yield())
5873 return posix_error();
5874 Py_RETURN_NONE;
5875}
5876
Benjamin Peterson2740af82011-08-02 17:41:34 -05005877#ifdef HAVE_SCHED_SETAFFINITY
5878
Antoine Pitrou84869872012-08-04 16:16:35 +02005879/* The minimum number of CPUs allocated in a cpu_set_t */
5880static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005881
5882PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5883"sched_setaffinity(pid, cpu_set)\n\n\
5884Set the affinity of the process with PID *pid* to *cpu_set*.");
5885
5886static PyObject *
5887posix_sched_setaffinity(PyObject *self, PyObject *args)
5888{
5889 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005890 int ncpus;
5891 size_t setsize;
5892 cpu_set_t *mask = NULL;
5893 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005894
Antoine Pitrou84869872012-08-04 16:16:35 +02005895 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5896 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005897 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005898
5899 iterator = PyObject_GetIter(iterable);
5900 if (iterator == NULL)
5901 return NULL;
5902
5903 ncpus = NCPUS_START;
5904 setsize = CPU_ALLOC_SIZE(ncpus);
5905 mask = CPU_ALLOC(ncpus);
5906 if (mask == NULL) {
5907 PyErr_NoMemory();
5908 goto error;
5909 }
5910 CPU_ZERO_S(setsize, mask);
5911
5912 while ((item = PyIter_Next(iterator))) {
5913 long cpu;
5914 if (!PyLong_Check(item)) {
5915 PyErr_Format(PyExc_TypeError,
5916 "expected an iterator of ints, "
5917 "but iterator yielded %R",
5918 Py_TYPE(item));
5919 Py_DECREF(item);
5920 goto error;
5921 }
5922 cpu = PyLong_AsLong(item);
5923 Py_DECREF(item);
5924 if (cpu < 0) {
5925 if (!PyErr_Occurred())
5926 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5927 goto error;
5928 }
5929 if (cpu > INT_MAX - 1) {
5930 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5931 goto error;
5932 }
5933 if (cpu >= ncpus) {
5934 /* Grow CPU mask to fit the CPU number */
5935 int newncpus = ncpus;
5936 cpu_set_t *newmask;
5937 size_t newsetsize;
5938 while (newncpus <= cpu) {
5939 if (newncpus > INT_MAX / 2)
5940 newncpus = cpu + 1;
5941 else
5942 newncpus = newncpus * 2;
5943 }
5944 newmask = CPU_ALLOC(newncpus);
5945 if (newmask == NULL) {
5946 PyErr_NoMemory();
5947 goto error;
5948 }
5949 newsetsize = CPU_ALLOC_SIZE(newncpus);
5950 CPU_ZERO_S(newsetsize, newmask);
5951 memcpy(newmask, mask, setsize);
5952 CPU_FREE(mask);
5953 setsize = newsetsize;
5954 mask = newmask;
5955 ncpus = newncpus;
5956 }
5957 CPU_SET_S(cpu, setsize, mask);
5958 }
5959 Py_CLEAR(iterator);
5960
5961 if (sched_setaffinity(pid, setsize, mask)) {
5962 posix_error();
5963 goto error;
5964 }
5965 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005966 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005967
5968error:
5969 if (mask)
5970 CPU_FREE(mask);
5971 Py_XDECREF(iterator);
5972 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005973}
5974
5975PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5976"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5977Return the affinity of the process with PID *pid*.\n\
5978The returned cpu_set will be of size *ncpus*.");
5979
5980static PyObject *
5981posix_sched_getaffinity(PyObject *self, PyObject *args)
5982{
5983 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005984 int cpu, ncpus, count;
5985 size_t setsize;
5986 cpu_set_t *mask = NULL;
5987 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005988
Antoine Pitrou84869872012-08-04 16:16:35 +02005989 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5990 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005991 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005992
5993 ncpus = NCPUS_START;
5994 while (1) {
5995 setsize = CPU_ALLOC_SIZE(ncpus);
5996 mask = CPU_ALLOC(ncpus);
5997 if (mask == NULL)
5998 return PyErr_NoMemory();
5999 if (sched_getaffinity(pid, setsize, mask) == 0)
6000 break;
6001 CPU_FREE(mask);
6002 if (errno != EINVAL)
6003 return posix_error();
6004 if (ncpus > INT_MAX / 2) {
6005 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6006 "a large enough CPU set");
6007 return NULL;
6008 }
6009 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006010 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006011
6012 res = PySet_New(NULL);
6013 if (res == NULL)
6014 goto error;
6015 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6016 if (CPU_ISSET_S(cpu, setsize, mask)) {
6017 PyObject *cpu_num = PyLong_FromLong(cpu);
6018 --count;
6019 if (cpu_num == NULL)
6020 goto error;
6021 if (PySet_Add(res, cpu_num)) {
6022 Py_DECREF(cpu_num);
6023 goto error;
6024 }
6025 Py_DECREF(cpu_num);
6026 }
6027 }
6028 CPU_FREE(mask);
6029 return res;
6030
6031error:
6032 if (mask)
6033 CPU_FREE(mask);
6034 Py_XDECREF(res);
6035 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006036}
6037
Benjamin Peterson2740af82011-08-02 17:41:34 -05006038#endif /* HAVE_SCHED_SETAFFINITY */
6039
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006040#endif /* HAVE_SCHED_H */
6041
Neal Norwitzb59798b2003-03-21 01:43:31 +00006042/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006043/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6044#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006045#define DEV_PTY_FILE "/dev/ptc"
6046#define HAVE_DEV_PTMX
6047#else
6048#define DEV_PTY_FILE "/dev/ptmx"
6049#endif
6050
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006051#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006052#ifdef HAVE_PTY_H
6053#include <pty.h>
6054#else
6055#ifdef HAVE_LIBUTIL_H
6056#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006057#else
6058#ifdef HAVE_UTIL_H
6059#include <util.h>
6060#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006061#endif /* HAVE_LIBUTIL_H */
6062#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006063#ifdef HAVE_STROPTS_H
6064#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006065#endif
6066#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006067
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006068#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006069PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006070"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006071Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006072
6073static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006074posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006075{
Victor Stinner8c62be82010-05-06 00:08:46 +00006076 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006077#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006078 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006079#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006080#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006081 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006082#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006083 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006084#endif
6085#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006086
Thomas Wouters70c21a12000-07-14 14:28:33 +00006087#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006088 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6089 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006090#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006091 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6092 if (slave_name == NULL)
6093 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006094
Victor Stinner8c62be82010-05-06 00:08:46 +00006095 slave_fd = open(slave_name, O_RDWR);
6096 if (slave_fd < 0)
6097 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006098#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006099 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6100 if (master_fd < 0)
6101 return posix_error();
6102 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6103 /* change permission of slave */
6104 if (grantpt(master_fd) < 0) {
6105 PyOS_setsig(SIGCHLD, sig_saved);
6106 return posix_error();
6107 }
6108 /* unlock slave */
6109 if (unlockpt(master_fd) < 0) {
6110 PyOS_setsig(SIGCHLD, sig_saved);
6111 return posix_error();
6112 }
6113 PyOS_setsig(SIGCHLD, sig_saved);
6114 slave_name = ptsname(master_fd); /* get name of slave */
6115 if (slave_name == NULL)
6116 return posix_error();
6117 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6118 if (slave_fd < 0)
6119 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006120#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006121 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6122 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006123#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006125#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006126#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006127#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006128
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006130
Fred Drake8cef4cf2000-06-28 16:40:38 +00006131}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006132#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006133
6134#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006136"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006137Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6138Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006140
6141static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006142posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006143{
Victor Stinner8c62be82010-05-06 00:08:46 +00006144 int master_fd = -1, result = 0;
6145 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006146
Victor Stinner8c62be82010-05-06 00:08:46 +00006147 _PyImport_AcquireLock();
6148 pid = forkpty(&master_fd, NULL, NULL, NULL);
6149 if (pid == 0) {
6150 /* child: this clobbers and resets the import lock. */
6151 PyOS_AfterFork();
6152 } else {
6153 /* parent: release the import lock. */
6154 result = _PyImport_ReleaseLock();
6155 }
6156 if (pid == -1)
6157 return posix_error();
6158 if (result < 0) {
6159 /* Don't clobber the OSError if the fork failed. */
6160 PyErr_SetString(PyExc_RuntimeError,
6161 "not holding the import lock");
6162 return NULL;
6163 }
6164 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006165}
6166#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006167
Ross Lagerwall7807c352011-03-17 20:20:30 +02006168
Guido van Rossumad0ee831995-03-01 10:34:45 +00006169#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006170PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006171"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006173
Barry Warsaw53699e91996-12-10 23:23:01 +00006174static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006175posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006176{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006177 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006178}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006179#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006181
Guido van Rossumad0ee831995-03-01 10:34:45 +00006182#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006183PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006184"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006186
Barry Warsaw53699e91996-12-10 23:23:01 +00006187static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006188posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006189{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006190 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006191}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006192#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006194
Guido van Rossumad0ee831995-03-01 10:34:45 +00006195#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006196PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006197"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006199
Barry Warsaw53699e91996-12-10 23:23:01 +00006200static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006201posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006202{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006203 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006204}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006205#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006208PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006209"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006210Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006211
Barry Warsaw53699e91996-12-10 23:23:01 +00006212static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006213posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006214{
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006216}
6217
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006218#ifdef HAVE_GETGROUPLIST
6219PyDoc_STRVAR(posix_getgrouplist__doc__,
6220"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6221Returns a list of groups to which a user belongs.\n\n\
6222 user: username to lookup\n\
6223 group: base group id of the user");
6224
6225static PyObject *
6226posix_getgrouplist(PyObject *self, PyObject *args)
6227{
6228#ifdef NGROUPS_MAX
6229#define MAX_GROUPS NGROUPS_MAX
6230#else
6231 /* defined to be 16 on Solaris7, so this should be a small number */
6232#define MAX_GROUPS 64
6233#endif
6234
6235 const char *user;
6236 int i, ngroups;
6237 PyObject *list;
6238#ifdef __APPLE__
6239 int *groups, basegid;
6240#else
6241 gid_t *groups, basegid;
6242#endif
6243 ngroups = MAX_GROUPS;
6244
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006245#ifdef __APPLE__
6246 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006247 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006248#else
6249 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6250 _Py_Gid_Converter, &basegid))
6251 return NULL;
6252#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006253
6254#ifdef __APPLE__
6255 groups = PyMem_Malloc(ngroups * sizeof(int));
6256#else
6257 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6258#endif
6259 if (groups == NULL)
6260 return PyErr_NoMemory();
6261
6262 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6263 PyMem_Del(groups);
6264 return posix_error();
6265 }
6266
6267 list = PyList_New(ngroups);
6268 if (list == NULL) {
6269 PyMem_Del(groups);
6270 return NULL;
6271 }
6272
6273 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006274#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006275 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006276#else
6277 PyObject *o = _PyLong_FromGid(groups[i]);
6278#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006279 if (o == NULL) {
6280 Py_DECREF(list);
6281 PyMem_Del(groups);
6282 return NULL;
6283 }
6284 PyList_SET_ITEM(list, i, o);
6285 }
6286
6287 PyMem_Del(groups);
6288
6289 return list;
6290}
6291#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006292
Fred Drakec9680921999-12-13 16:37:25 +00006293#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006294PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006295"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006296Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006297
6298static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006299posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006300{
6301 PyObject *result = NULL;
6302
Fred Drakec9680921999-12-13 16:37:25 +00006303#ifdef NGROUPS_MAX
6304#define MAX_GROUPS NGROUPS_MAX
6305#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006306 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006307#define MAX_GROUPS 64
6308#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006309 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006310
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006311 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006312 * This is a helper variable to store the intermediate result when
6313 * that happens.
6314 *
6315 * To keep the code readable the OSX behaviour is unconditional,
6316 * according to the POSIX spec this should be safe on all unix-y
6317 * systems.
6318 */
6319 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006321
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006323 if (n < 0) {
6324 if (errno == EINVAL) {
6325 n = getgroups(0, NULL);
6326 if (n == -1) {
6327 return posix_error();
6328 }
6329 if (n == 0) {
6330 /* Avoid malloc(0) */
6331 alt_grouplist = grouplist;
6332 } else {
6333 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6334 if (alt_grouplist == NULL) {
6335 errno = EINVAL;
6336 return posix_error();
6337 }
6338 n = getgroups(n, alt_grouplist);
6339 if (n == -1) {
6340 PyMem_Free(alt_grouplist);
6341 return posix_error();
6342 }
6343 }
6344 } else {
6345 return posix_error();
6346 }
6347 }
6348 result = PyList_New(n);
6349 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006350 int i;
6351 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006352 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006354 Py_DECREF(result);
6355 result = NULL;
6356 break;
Fred Drakec9680921999-12-13 16:37:25 +00006357 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006359 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006360 }
6361
6362 if (alt_grouplist != grouplist) {
6363 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006365
Fred Drakec9680921999-12-13 16:37:25 +00006366 return result;
6367}
6368#endif
6369
Antoine Pitroub7572f02009-12-02 20:46:48 +00006370#ifdef HAVE_INITGROUPS
6371PyDoc_STRVAR(posix_initgroups__doc__,
6372"initgroups(username, gid) -> None\n\n\
6373Call the system initgroups() to initialize the group access list with all of\n\
6374the groups of which the specified username is a member, plus the specified\n\
6375group id.");
6376
6377static PyObject *
6378posix_initgroups(PyObject *self, PyObject *args)
6379{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006380 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006382 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006383#ifdef __APPLE__
6384 int gid;
6385#else
6386 gid_t gid;
6387#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006388
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006389#ifdef __APPLE__
6390 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6391 PyUnicode_FSConverter, &oname,
6392 &gid))
6393#else
6394 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6395 PyUnicode_FSConverter, &oname,
6396 _Py_Gid_Converter, &gid))
6397#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006399 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006400
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006401 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006402 Py_DECREF(oname);
6403 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006405
Victor Stinner8c62be82010-05-06 00:08:46 +00006406 Py_INCREF(Py_None);
6407 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006408}
6409#endif
6410
Martin v. Löwis606edc12002-06-13 21:09:11 +00006411#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006412PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006413"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006414Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006415
6416static PyObject *
6417posix_getpgid(PyObject *self, PyObject *args)
6418{
Victor Stinner8c62be82010-05-06 00:08:46 +00006419 pid_t pid, pgid;
6420 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6421 return NULL;
6422 pgid = getpgid(pid);
6423 if (pgid < 0)
6424 return posix_error();
6425 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006426}
6427#endif /* HAVE_GETPGID */
6428
6429
Guido van Rossumb6775db1994-08-01 11:34:53 +00006430#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006431PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006432"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006433Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006434
Barry Warsaw53699e91996-12-10 23:23:01 +00006435static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006436posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006437{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006438#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006439 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006440#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006442#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006443}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006444#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006446
Guido van Rossumb6775db1994-08-01 11:34:53 +00006447#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006448PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006449"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006450Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006451
Barry Warsaw53699e91996-12-10 23:23:01 +00006452static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006453posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006454{
Guido van Rossum64933891994-10-20 21:56:42 +00006455#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006456 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006457#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006459#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 return posix_error();
6461 Py_INCREF(Py_None);
6462 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006463}
6464
Guido van Rossumb6775db1994-08-01 11:34:53 +00006465#endif /* HAVE_SETPGRP */
6466
Guido van Rossumad0ee831995-03-01 10:34:45 +00006467#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006468
6469#ifdef MS_WINDOWS
6470#include <tlhelp32.h>
6471
6472static PyObject*
6473win32_getppid()
6474{
6475 HANDLE snapshot;
6476 pid_t mypid;
6477 PyObject* result = NULL;
6478 BOOL have_record;
6479 PROCESSENTRY32 pe;
6480
6481 mypid = getpid(); /* This function never fails */
6482
6483 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6484 if (snapshot == INVALID_HANDLE_VALUE)
6485 return PyErr_SetFromWindowsErr(GetLastError());
6486
6487 pe.dwSize = sizeof(pe);
6488 have_record = Process32First(snapshot, &pe);
6489 while (have_record) {
6490 if (mypid == (pid_t)pe.th32ProcessID) {
6491 /* We could cache the ulong value in a static variable. */
6492 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6493 break;
6494 }
6495
6496 have_record = Process32Next(snapshot, &pe);
6497 }
6498
6499 /* If our loop exits and our pid was not found (result will be NULL)
6500 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6501 * error anyway, so let's raise it. */
6502 if (!result)
6503 result = PyErr_SetFromWindowsErr(GetLastError());
6504
6505 CloseHandle(snapshot);
6506
6507 return result;
6508}
6509#endif /*MS_WINDOWS*/
6510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006511PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006512"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006513Return the parent's process id. If the parent process has already exited,\n\
6514Windows machines will still return its id; others systems will return the id\n\
6515of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006516
Barry Warsaw53699e91996-12-10 23:23:01 +00006517static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006518posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006519{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006520#ifdef MS_WINDOWS
6521 return win32_getppid();
6522#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006524#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006525}
6526#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006528
Fred Drake12c6e2d1999-12-14 21:25:03 +00006529#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006531"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006532Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006533
6534static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006535posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006536{
Victor Stinner8c62be82010-05-06 00:08:46 +00006537 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006538#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006539 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006540 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006541
6542 if (GetUserNameW(user_name, &num_chars)) {
6543 /* num_chars is the number of unicode chars plus null terminator */
6544 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006545 }
6546 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006547 result = PyErr_SetFromWindowsErr(GetLastError());
6548#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 char *name;
6550 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006551
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 errno = 0;
6553 name = getlogin();
6554 if (name == NULL) {
6555 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006556 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006557 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006558 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 }
6560 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006561 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006563#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006564 return result;
6565}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006566#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006567
Guido van Rossumad0ee831995-03-01 10:34:45 +00006568#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006569PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006570"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006571Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006572
Barry Warsaw53699e91996-12-10 23:23:01 +00006573static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006574posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006575{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006576 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006577}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006578#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006580
Guido van Rossumad0ee831995-03-01 10:34:45 +00006581#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006582PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006583"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006584Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006585
Barry Warsaw53699e91996-12-10 23:23:01 +00006586static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006587posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006588{
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 pid_t pid;
6590 int sig;
6591 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6592 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006593#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006594 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6595 APIRET rc;
6596 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006597 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006598
6599 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6600 APIRET rc;
6601 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006602 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006603
6604 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006605 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006606#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 if (kill(pid, sig) == -1)
6608 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006609#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 Py_INCREF(Py_None);
6611 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006612}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006613#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006614
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006615#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006616PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006617"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006618Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006619
6620static PyObject *
6621posix_killpg(PyObject *self, PyObject *args)
6622{
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 int sig;
6624 pid_t pgid;
6625 /* XXX some man pages make the `pgid` parameter an int, others
6626 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6627 take the same type. Moreover, pid_t is always at least as wide as
6628 int (else compilation of this module fails), which is safe. */
6629 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6630 return NULL;
6631 if (killpg(pgid, sig) == -1)
6632 return posix_error();
6633 Py_INCREF(Py_None);
6634 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006635}
6636#endif
6637
Brian Curtineb24d742010-04-12 17:16:38 +00006638#ifdef MS_WINDOWS
6639PyDoc_STRVAR(win32_kill__doc__,
6640"kill(pid, sig)\n\n\
6641Kill a process with a signal.");
6642
6643static PyObject *
6644win32_kill(PyObject *self, PyObject *args)
6645{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006646 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 DWORD pid, sig, err;
6648 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006649
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6651 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006652
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 /* Console processes which share a common console can be sent CTRL+C or
6654 CTRL+BREAK events, provided they handle said events. */
6655 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6656 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6657 err = GetLastError();
6658 PyErr_SetFromWindowsErr(err);
6659 }
6660 else
6661 Py_RETURN_NONE;
6662 }
Brian Curtineb24d742010-04-12 17:16:38 +00006663
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6665 attempt to open and terminate the process. */
6666 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6667 if (handle == NULL) {
6668 err = GetLastError();
6669 return PyErr_SetFromWindowsErr(err);
6670 }
Brian Curtineb24d742010-04-12 17:16:38 +00006671
Victor Stinner8c62be82010-05-06 00:08:46 +00006672 if (TerminateProcess(handle, sig) == 0) {
6673 err = GetLastError();
6674 result = PyErr_SetFromWindowsErr(err);
6675 } else {
6676 Py_INCREF(Py_None);
6677 result = Py_None;
6678 }
Brian Curtineb24d742010-04-12 17:16:38 +00006679
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 CloseHandle(handle);
6681 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006682}
6683#endif /* MS_WINDOWS */
6684
Guido van Rossumc0125471996-06-28 18:55:32 +00006685#ifdef HAVE_PLOCK
6686
6687#ifdef HAVE_SYS_LOCK_H
6688#include <sys/lock.h>
6689#endif
6690
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006692"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006693Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006694
Barry Warsaw53699e91996-12-10 23:23:01 +00006695static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006696posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006697{
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 int op;
6699 if (!PyArg_ParseTuple(args, "i:plock", &op))
6700 return NULL;
6701 if (plock(op) == -1)
6702 return posix_error();
6703 Py_INCREF(Py_None);
6704 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006705}
6706#endif
6707
Guido van Rossumb6775db1994-08-01 11:34:53 +00006708#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006710"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006711Set the current process's user id.");
6712
Barry Warsaw53699e91996-12-10 23:23:01 +00006713static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006714posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006715{
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006717 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 if (setuid(uid) < 0)
6720 return posix_error();
6721 Py_INCREF(Py_None);
6722 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006723}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006724#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006726
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006727#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006728PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006729"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006730Set the current process's effective user id.");
6731
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006732static PyObject *
6733posix_seteuid (PyObject *self, PyObject *args)
6734{
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006736 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006738 if (seteuid(euid) < 0) {
6739 return posix_error();
6740 } else {
6741 Py_INCREF(Py_None);
6742 return Py_None;
6743 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006744}
6745#endif /* HAVE_SETEUID */
6746
6747#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006748PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006749"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006750Set the current process's effective group id.");
6751
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006752static PyObject *
6753posix_setegid (PyObject *self, PyObject *args)
6754{
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006756 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 if (setegid(egid) < 0) {
6759 return posix_error();
6760 } else {
6761 Py_INCREF(Py_None);
6762 return Py_None;
6763 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006764}
6765#endif /* HAVE_SETEGID */
6766
6767#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006768PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006769"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006770Set the current process's real and effective user ids.");
6771
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006772static PyObject *
6773posix_setreuid (PyObject *self, PyObject *args)
6774{
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006776 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6777 _Py_Uid_Converter, &ruid,
6778 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 if (setreuid(ruid, euid) < 0) {
6781 return posix_error();
6782 } else {
6783 Py_INCREF(Py_None);
6784 return Py_None;
6785 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006786}
6787#endif /* HAVE_SETREUID */
6788
6789#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006790PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006791"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006792Set the current process's real and effective group ids.");
6793
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006794static PyObject *
6795posix_setregid (PyObject *self, PyObject *args)
6796{
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006798 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6799 _Py_Gid_Converter, &rgid,
6800 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 if (setregid(rgid, egid) < 0) {
6803 return posix_error();
6804 } else {
6805 Py_INCREF(Py_None);
6806 return Py_None;
6807 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006808}
6809#endif /* HAVE_SETREGID */
6810
Guido van Rossumb6775db1994-08-01 11:34:53 +00006811#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006813"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006815
Barry Warsaw53699e91996-12-10 23:23:01 +00006816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006817posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006818{
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006820 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 if (setgid(gid) < 0)
6823 return posix_error();
6824 Py_INCREF(Py_None);
6825 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006826}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006827#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006828
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006829#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006830PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006831"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006833
6834static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006835posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006836{
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 int i, len;
6838 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006839
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 if (!PySequence_Check(groups)) {
6841 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6842 return NULL;
6843 }
6844 len = PySequence_Size(groups);
6845 if (len > MAX_GROUPS) {
6846 PyErr_SetString(PyExc_ValueError, "too many groups");
6847 return NULL;
6848 }
6849 for(i = 0; i < len; i++) {
6850 PyObject *elem;
6851 elem = PySequence_GetItem(groups, i);
6852 if (!elem)
6853 return NULL;
6854 if (!PyLong_Check(elem)) {
6855 PyErr_SetString(PyExc_TypeError,
6856 "groups must be integers");
6857 Py_DECREF(elem);
6858 return NULL;
6859 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006860 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 Py_DECREF(elem);
6862 return NULL;
6863 }
6864 }
6865 Py_DECREF(elem);
6866 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006867
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 if (setgroups(len, grouplist) < 0)
6869 return posix_error();
6870 Py_INCREF(Py_None);
6871 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006872}
6873#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006874
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006875#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6876static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006877wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006878{
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 PyObject *result;
6880 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006881 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 if (pid == -1)
6884 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006885
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 if (struct_rusage == NULL) {
6887 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6888 if (m == NULL)
6889 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006890 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006891 Py_DECREF(m);
6892 if (struct_rusage == NULL)
6893 return NULL;
6894 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006895
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6897 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6898 if (!result)
6899 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900
6901#ifndef doubletime
6902#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6903#endif
6904
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006906 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006908 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006909#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6911 SET_INT(result, 2, ru->ru_maxrss);
6912 SET_INT(result, 3, ru->ru_ixrss);
6913 SET_INT(result, 4, ru->ru_idrss);
6914 SET_INT(result, 5, ru->ru_isrss);
6915 SET_INT(result, 6, ru->ru_minflt);
6916 SET_INT(result, 7, ru->ru_majflt);
6917 SET_INT(result, 8, ru->ru_nswap);
6918 SET_INT(result, 9, ru->ru_inblock);
6919 SET_INT(result, 10, ru->ru_oublock);
6920 SET_INT(result, 11, ru->ru_msgsnd);
6921 SET_INT(result, 12, ru->ru_msgrcv);
6922 SET_INT(result, 13, ru->ru_nsignals);
6923 SET_INT(result, 14, ru->ru_nvcsw);
6924 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925#undef SET_INT
6926
Victor Stinner8c62be82010-05-06 00:08:46 +00006927 if (PyErr_Occurred()) {
6928 Py_DECREF(result);
6929 return NULL;
6930 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006931
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006933}
6934#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6935
6936#ifdef HAVE_WAIT3
6937PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006938"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006939Wait for completion of a child process.");
6940
6941static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006942posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006943{
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 pid_t pid;
6945 int options;
6946 struct rusage ru;
6947 WAIT_TYPE status;
6948 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006949
Victor Stinner4195b5c2012-02-08 23:03:19 +01006950 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006952
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 Py_BEGIN_ALLOW_THREADS
6954 pid = wait3(&status, options, &ru);
6955 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006956
Victor Stinner4195b5c2012-02-08 23:03:19 +01006957 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006958}
6959#endif /* HAVE_WAIT3 */
6960
6961#ifdef HAVE_WAIT4
6962PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006963"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006964Wait for completion of a given child process.");
6965
6966static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006967posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006968{
Victor Stinner8c62be82010-05-06 00:08:46 +00006969 pid_t pid;
6970 int options;
6971 struct rusage ru;
6972 WAIT_TYPE status;
6973 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006974
Victor Stinner4195b5c2012-02-08 23:03:19 +01006975 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006977
Victor Stinner8c62be82010-05-06 00:08:46 +00006978 Py_BEGIN_ALLOW_THREADS
6979 pid = wait4(pid, &status, options, &ru);
6980 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006981
Victor Stinner4195b5c2012-02-08 23:03:19 +01006982 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006983}
6984#endif /* HAVE_WAIT4 */
6985
Ross Lagerwall7807c352011-03-17 20:20:30 +02006986#if defined(HAVE_WAITID) && !defined(__APPLE__)
6987PyDoc_STRVAR(posix_waitid__doc__,
6988"waitid(idtype, id, options) -> waitid_result\n\n\
6989Wait for the completion of one or more child processes.\n\n\
6990idtype can be P_PID, P_PGID or P_ALL.\n\
6991id specifies the pid to wait on.\n\
6992options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6993or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6994Returns either waitid_result or None if WNOHANG is specified and there are\n\
6995no children in a waitable state.");
6996
6997static PyObject *
6998posix_waitid(PyObject *self, PyObject *args)
6999{
7000 PyObject *result;
7001 idtype_t idtype;
7002 id_t id;
7003 int options, res;
7004 siginfo_t si;
7005 si.si_pid = 0;
7006 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7007 return NULL;
7008 Py_BEGIN_ALLOW_THREADS
7009 res = waitid(idtype, id, &si, options);
7010 Py_END_ALLOW_THREADS
7011 if (res == -1)
7012 return posix_error();
7013
7014 if (si.si_pid == 0)
7015 Py_RETURN_NONE;
7016
7017 result = PyStructSequence_New(&WaitidResultType);
7018 if (!result)
7019 return NULL;
7020
7021 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007022 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007023 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7024 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7025 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7026 if (PyErr_Occurred()) {
7027 Py_DECREF(result);
7028 return NULL;
7029 }
7030
7031 return result;
7032}
7033#endif
7034
Guido van Rossumb6775db1994-08-01 11:34:53 +00007035#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007036PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007037"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007038Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007039
Barry Warsaw53699e91996-12-10 23:23:01 +00007040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007041posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007042{
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 pid_t pid;
7044 int options;
7045 WAIT_TYPE status;
7046 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007047
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7049 return NULL;
7050 Py_BEGIN_ALLOW_THREADS
7051 pid = waitpid(pid, &status, options);
7052 Py_END_ALLOW_THREADS
7053 if (pid == -1)
7054 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007055
Victor Stinner8c62be82010-05-06 00:08:46 +00007056 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007057}
7058
Tim Petersab034fa2002-02-01 11:27:43 +00007059#elif defined(HAVE_CWAIT)
7060
7061/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007062PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007063"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007064"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007065
7066static PyObject *
7067posix_waitpid(PyObject *self, PyObject *args)
7068{
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 Py_intptr_t pid;
7070 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007071
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7073 return NULL;
7074 Py_BEGIN_ALLOW_THREADS
7075 pid = _cwait(&status, pid, options);
7076 Py_END_ALLOW_THREADS
7077 if (pid == -1)
7078 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007079
Victor Stinner8c62be82010-05-06 00:08:46 +00007080 /* shift the status left a byte so this is more like the POSIX waitpid */
7081 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007082}
7083#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007084
Guido van Rossumad0ee831995-03-01 10:34:45 +00007085#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007086PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007087"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007088Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007089
Barry Warsaw53699e91996-12-10 23:23:01 +00007090static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007091posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007092{
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 pid_t pid;
7094 WAIT_TYPE status;
7095 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007096
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 Py_BEGIN_ALLOW_THREADS
7098 pid = wait(&status);
7099 Py_END_ALLOW_THREADS
7100 if (pid == -1)
7101 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007102
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007104}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007105#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007107
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7109PyDoc_STRVAR(readlink__doc__,
7110"readlink(path, *, dir_fd=None) -> path\n\n\
7111Return a string representing the path to which the symbolic link points.\n\
7112\n\
7113If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7114 and path should be relative; path will then be relative to that directory.\n\
7115dir_fd may not be implemented on your platform.\n\
7116 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007117#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007118
Guido van Rossumb6775db1994-08-01 11:34:53 +00007119#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007120
Barry Warsaw53699e91996-12-10 23:23:01 +00007121static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007123{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124 path_t path;
7125 int dir_fd = DEFAULT_DIR_FD;
7126 char buffer[MAXPATHLEN];
7127 ssize_t length;
7128 PyObject *return_value = NULL;
7129 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007130
Larry Hastings9cf065c2012-06-22 16:30:09 -07007131 memset(&path, 0, sizeof(path));
7132 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7133 path_converter, &path,
7134#ifdef HAVE_READLINKAT
7135 dir_fd_converter, &dir_fd
7136#else
7137 dir_fd_unavailable, &dir_fd
7138#endif
7139 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007140 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007141
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007143#ifdef HAVE_READLINKAT
7144 if (dir_fd != DEFAULT_DIR_FD)
7145 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007146 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007147#endif
7148 length = readlink(path.narrow, buffer, sizeof(buffer));
7149 Py_END_ALLOW_THREADS
7150
7151 if (length < 0) {
7152 return_value = path_posix_error("readlink", &path);
7153 goto exit;
7154 }
7155
7156 if (PyUnicode_Check(path.object))
7157 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7158 else
7159 return_value = PyBytes_FromStringAndSize(buffer, length);
7160exit:
7161 path_cleanup(&path);
7162 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007163}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164
7165
Guido van Rossumb6775db1994-08-01 11:34:53 +00007166#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007168
Larry Hastings9cf065c2012-06-22 16:30:09 -07007169#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007170PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007171"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7172Create a symbolic link pointing to src named dst.\n\n\
7173target_is_directory is required on Windows if the target is to be\n\
7174 interpreted as a directory. (On Windows, symlink requires\n\
7175 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7176 target_is_directory is ignored on non-Windows platforms.\n\
7177\n\
7178If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7179 and path should be relative; path will then be relative to that directory.\n\
7180dir_fd may not be implemented on your platform.\n\
7181 If it is unavailable, using it will raise a NotImplementedError.");
7182
7183#if defined(MS_WINDOWS)
7184
7185/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7186static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7187static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7188static int
7189check_CreateSymbolicLink()
7190{
7191 HINSTANCE hKernel32;
7192 /* only recheck */
7193 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7194 return 1;
7195 hKernel32 = GetModuleHandleW(L"KERNEL32");
7196 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7197 "CreateSymbolicLinkW");
7198 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7199 "CreateSymbolicLinkA");
7200 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7201}
7202
7203#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007204
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007205static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007206posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007207{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007208 path_t src;
7209 path_t dst;
7210 int dir_fd = DEFAULT_DIR_FD;
7211 int target_is_directory = 0;
7212 static char *keywords[] = {"src", "dst", "target_is_directory",
7213 "dir_fd", NULL};
7214 PyObject *return_value;
7215#ifdef MS_WINDOWS
7216 DWORD result;
7217#else
7218 int result;
7219#endif
7220
7221 memset(&src, 0, sizeof(src));
7222 src.argument_name = "src";
7223 memset(&dst, 0, sizeof(dst));
7224 dst.argument_name = "dst";
7225
7226#ifdef MS_WINDOWS
7227 if (!check_CreateSymbolicLink()) {
7228 PyErr_SetString(PyExc_NotImplementedError,
7229 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007230 return NULL;
7231 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007232 if (!win32_can_symlink) {
7233 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007234 return NULL;
7235 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007236#endif
7237
7238 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7239 keywords,
7240 path_converter, &src,
7241 path_converter, &dst,
7242 &target_is_directory,
7243#ifdef HAVE_SYMLINKAT
7244 dir_fd_converter, &dir_fd
7245#else
7246 dir_fd_unavailable, &dir_fd
7247#endif
7248 ))
7249 return NULL;
7250
7251 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7252 PyErr_SetString(PyExc_ValueError,
7253 "symlink: src and dst must be the same type");
7254 return_value = NULL;
7255 goto exit;
7256 }
7257
7258#ifdef MS_WINDOWS
7259 Py_BEGIN_ALLOW_THREADS
7260 if (dst.wide)
7261 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7262 target_is_directory);
7263 else
7264 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7265 target_is_directory);
7266 Py_END_ALLOW_THREADS
7267
7268 if (!result) {
7269 return_value = win32_error_object("symlink", src.object);
7270 goto exit;
7271 }
7272
7273#else
7274
7275 Py_BEGIN_ALLOW_THREADS
7276#if HAVE_SYMLINKAT
7277 if (dir_fd != DEFAULT_DIR_FD)
7278 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7279 else
7280#endif
7281 result = symlink(src.narrow, dst.narrow);
7282 Py_END_ALLOW_THREADS
7283
7284 if (result) {
7285 return_value = path_error("symlink", &dst);
7286 goto exit;
7287 }
7288#endif
7289
7290 return_value = Py_None;
7291 Py_INCREF(Py_None);
7292 goto exit; /* silence "unused label" warning */
7293exit:
7294 path_cleanup(&src);
7295 path_cleanup(&dst);
7296 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007297}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007298
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007299#endif /* HAVE_SYMLINK */
7300
Larry Hastings9cf065c2012-06-22 16:30:09 -07007301
Brian Curtind40e6f72010-07-08 21:39:08 +00007302#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7303
Brian Curtind40e6f72010-07-08 21:39:08 +00007304static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007305win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007306{
7307 wchar_t *path;
7308 DWORD n_bytes_returned;
7309 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007310 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007311 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007312 HANDLE reparse_point_handle;
7313
7314 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7315 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7316 wchar_t *print_name;
7317
Larry Hastings9cf065c2012-06-22 16:30:09 -07007318 static char *keywords[] = {"path", "dir_fd", NULL};
7319
7320 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7321 &po,
7322 dir_fd_unavailable, &dir_fd
7323 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007324 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007325
Victor Stinnereb5657a2011-09-30 01:44:27 +02007326 path = PyUnicode_AsUnicode(po);
7327 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007328 return NULL;
7329
7330 /* First get a handle to the reparse point */
7331 Py_BEGIN_ALLOW_THREADS
7332 reparse_point_handle = CreateFileW(
7333 path,
7334 0,
7335 0,
7336 0,
7337 OPEN_EXISTING,
7338 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7339 0);
7340 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007341
Brian Curtind40e6f72010-07-08 21:39:08 +00007342 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007343 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007344
Brian Curtind40e6f72010-07-08 21:39:08 +00007345 Py_BEGIN_ALLOW_THREADS
7346 /* New call DeviceIoControl to read the reparse point */
7347 io_result = DeviceIoControl(
7348 reparse_point_handle,
7349 FSCTL_GET_REPARSE_POINT,
7350 0, 0, /* in buffer */
7351 target_buffer, sizeof(target_buffer),
7352 &n_bytes_returned,
7353 0 /* we're not using OVERLAPPED_IO */
7354 );
7355 CloseHandle(reparse_point_handle);
7356 Py_END_ALLOW_THREADS
7357
7358 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007359 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007360
7361 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7362 {
7363 PyErr_SetString(PyExc_ValueError,
7364 "not a symbolic link");
7365 return NULL;
7366 }
Brian Curtin74e45612010-07-09 15:58:59 +00007367 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7368 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7369
7370 result = PyUnicode_FromWideChar(print_name,
7371 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007372 return result;
7373}
7374
7375#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7376
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007377
Larry Hastings605a62d2012-06-24 04:33:36 -07007378static PyStructSequence_Field times_result_fields[] = {
7379 {"user", "user time"},
7380 {"system", "system time"},
7381 {"children_user", "user time of children"},
7382 {"children_system", "system time of children"},
7383 {"elapsed", "elapsed time since an arbitrary point in the past"},
7384 {NULL}
7385};
7386
7387PyDoc_STRVAR(times_result__doc__,
7388"times_result: Result from os.times().\n\n\
7389This object may be accessed either as a tuple of\n\
7390 (user, system, children_user, children_system, elapsed),\n\
7391or via the attributes user, system, children_user, children_system,\n\
7392and elapsed.\n\
7393\n\
7394See os.times for more information.");
7395
7396static PyStructSequence_Desc times_result_desc = {
7397 "times_result", /* name */
7398 times_result__doc__, /* doc */
7399 times_result_fields,
7400 5
7401};
7402
7403static PyTypeObject TimesResultType;
7404
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007405#ifdef MS_WINDOWS
7406#define HAVE_TIMES /* mandatory, for the method table */
7407#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007408
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007409#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007410
7411static PyObject *
7412build_times_result(double user, double system,
7413 double children_user, double children_system,
7414 double elapsed)
7415{
7416 PyObject *value = PyStructSequence_New(&TimesResultType);
7417 if (value == NULL)
7418 return NULL;
7419
7420#define SET(i, field) \
7421 { \
7422 PyObject *o = PyFloat_FromDouble(field); \
7423 if (!o) { \
7424 Py_DECREF(value); \
7425 return NULL; \
7426 } \
7427 PyStructSequence_SET_ITEM(value, i, o); \
7428 } \
7429
7430 SET(0, user);
7431 SET(1, system);
7432 SET(2, children_user);
7433 SET(3, children_system);
7434 SET(4, elapsed);
7435
7436#undef SET
7437
7438 return value;
7439}
7440
7441PyDoc_STRVAR(posix_times__doc__,
7442"times() -> times_result\n\n\
7443Return an object containing floating point numbers indicating process\n\
7444times. The object behaves like a named tuple with these fields:\n\
7445 (utime, stime, cutime, cstime, elapsed_time)");
7446
Guido van Rossumd48f2521997-12-05 22:19:34 +00007447#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7448static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007449system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007450{
7451 ULONG value = 0;
7452
7453 Py_BEGIN_ALLOW_THREADS
7454 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7455 Py_END_ALLOW_THREADS
7456
7457 return value;
7458}
7459
7460static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007461posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007462{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007463 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007464 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007465 (double)0 /* t.tms_utime / HZ */,
7466 (double)0 /* t.tms_stime / HZ */,
7467 (double)0 /* t.tms_cutime / HZ */,
7468 (double)0 /* t.tms_cstime / HZ */,
7469 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007470}
Larry Hastings605a62d2012-06-24 04:33:36 -07007471#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007472static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007473posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007474{
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 FILETIME create, exit, kernel, user;
7476 HANDLE hProc;
7477 hProc = GetCurrentProcess();
7478 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7479 /* The fields of a FILETIME structure are the hi and lo part
7480 of a 64-bit value expressed in 100 nanosecond units.
7481 1e7 is one second in such units; 1e-7 the inverse.
7482 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7483 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007484 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007485 (double)(user.dwHighDateTime*429.4967296 +
7486 user.dwLowDateTime*1e-7),
7487 (double)(kernel.dwHighDateTime*429.4967296 +
7488 kernel.dwLowDateTime*1e-7),
7489 (double)0,
7490 (double)0,
7491 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007492}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007493#else /* Neither Windows nor OS/2 */
7494#define NEED_TICKS_PER_SECOND
7495static long ticks_per_second = -1;
7496static PyObject *
7497posix_times(PyObject *self, PyObject *noargs)
7498{
7499 struct tms t;
7500 clock_t c;
7501 errno = 0;
7502 c = times(&t);
7503 if (c == (clock_t) -1)
7504 return posix_error();
7505 return build_times_result(
7506 (double)t.tms_utime / ticks_per_second,
7507 (double)t.tms_stime / ticks_per_second,
7508 (double)t.tms_cutime / ticks_per_second,
7509 (double)t.tms_cstime / ticks_per_second,
7510 (double)c / ticks_per_second);
7511}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007512#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007513
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007514#endif /* HAVE_TIMES */
7515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007516
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007517#ifdef HAVE_GETSID
7518PyDoc_STRVAR(posix_getsid__doc__,
7519"getsid(pid) -> sid\n\n\
7520Call the system call getsid().");
7521
7522static PyObject *
7523posix_getsid(PyObject *self, PyObject *args)
7524{
Victor Stinner8c62be82010-05-06 00:08:46 +00007525 pid_t pid;
7526 int sid;
7527 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7528 return NULL;
7529 sid = getsid(pid);
7530 if (sid < 0)
7531 return posix_error();
7532 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007533}
7534#endif /* HAVE_GETSID */
7535
7536
Guido van Rossumb6775db1994-08-01 11:34:53 +00007537#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007538PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007539"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007540Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007541
Barry Warsaw53699e91996-12-10 23:23:01 +00007542static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007543posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007544{
Victor Stinner8c62be82010-05-06 00:08:46 +00007545 if (setsid() < 0)
7546 return posix_error();
7547 Py_INCREF(Py_None);
7548 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007549}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007550#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007551
Guido van Rossumb6775db1994-08-01 11:34:53 +00007552#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007553PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007554"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007555Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007556
Barry Warsaw53699e91996-12-10 23:23:01 +00007557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007558posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007559{
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 pid_t pid;
7561 int pgrp;
7562 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7563 return NULL;
7564 if (setpgid(pid, pgrp) < 0)
7565 return posix_error();
7566 Py_INCREF(Py_None);
7567 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007568}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007569#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007570
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007571
Guido van Rossumb6775db1994-08-01 11:34:53 +00007572#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007573PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007574"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007575Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007576
Barry Warsaw53699e91996-12-10 23:23:01 +00007577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007578posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007579{
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 int fd;
7581 pid_t pgid;
7582 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7583 return NULL;
7584 pgid = tcgetpgrp(fd);
7585 if (pgid < 0)
7586 return posix_error();
7587 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007588}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007589#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007590
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007591
Guido van Rossumb6775db1994-08-01 11:34:53 +00007592#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007593PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007594"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007595Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007596
Barry Warsaw53699e91996-12-10 23:23:01 +00007597static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007598posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007599{
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 int fd;
7601 pid_t pgid;
7602 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7603 return NULL;
7604 if (tcsetpgrp(fd, pgid) < 0)
7605 return posix_error();
7606 Py_INCREF(Py_None);
7607 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007608}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007609#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007610
Guido van Rossum687dd131993-05-17 08:34:16 +00007611/* Functions acting on file descriptors */
7612
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007613PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007614"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7615Open a file for low level IO. Returns a file handle (integer).\n\
7616\n\
7617If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7618 and path should be relative; path will then be relative to that directory.\n\
7619dir_fd may not be implemented on your platform.\n\
7620 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007621
Barry Warsaw53699e91996-12-10 23:23:01 +00007622static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007623posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007624{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007625 path_t path;
7626 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007628 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007629 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007630 PyObject *return_value = NULL;
7631 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007632
Larry Hastings9cf065c2012-06-22 16:30:09 -07007633 memset(&path, 0, sizeof(path));
7634 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7635 path_converter, &path,
7636 &flags, &mode,
7637#ifdef HAVE_OPENAT
7638 dir_fd_converter, &dir_fd
7639#else
7640 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007641#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007642 ))
7643 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007644
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007646#ifdef MS_WINDOWS
7647 if (path.wide)
7648 fd = _wopen(path.wide, flags, mode);
7649 else
7650#endif
7651#ifdef HAVE_OPENAT
7652 if (dir_fd != DEFAULT_DIR_FD)
7653 fd = openat(dir_fd, path.narrow, flags, mode);
7654 else
7655#endif
7656 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007658
Larry Hastings9cf065c2012-06-22 16:30:09 -07007659 if (fd == -1) {
7660#ifdef MS_WINDOWS
7661 /* force use of posix_error here for exact backwards compatibility */
7662 if (path.wide)
7663 return_value = posix_error();
7664 else
7665#endif
7666 return_value = path_error("open", &path);
7667 goto exit;
7668 }
7669
7670 return_value = PyLong_FromLong((long)fd);
7671
7672exit:
7673 path_cleanup(&path);
7674 return return_value;
7675}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007676
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007677PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007678"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007679Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007680
Barry Warsaw53699e91996-12-10 23:23:01 +00007681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007682posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007683{
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 int fd, res;
7685 if (!PyArg_ParseTuple(args, "i:close", &fd))
7686 return NULL;
7687 if (!_PyVerify_fd(fd))
7688 return posix_error();
7689 Py_BEGIN_ALLOW_THREADS
7690 res = close(fd);
7691 Py_END_ALLOW_THREADS
7692 if (res < 0)
7693 return posix_error();
7694 Py_INCREF(Py_None);
7695 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007696}
7697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007698
Victor Stinner8c62be82010-05-06 00:08:46 +00007699PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007700"closerange(fd_low, fd_high)\n\n\
7701Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7702
7703static PyObject *
7704posix_closerange(PyObject *self, PyObject *args)
7705{
Victor Stinner8c62be82010-05-06 00:08:46 +00007706 int fd_from, fd_to, i;
7707 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7708 return NULL;
7709 Py_BEGIN_ALLOW_THREADS
7710 for (i = fd_from; i < fd_to; i++)
7711 if (_PyVerify_fd(i))
7712 close(i);
7713 Py_END_ALLOW_THREADS
7714 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007715}
7716
7717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007718PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007719"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007720Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007721
Barry Warsaw53699e91996-12-10 23:23:01 +00007722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007723posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007724{
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 int fd;
7726 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7727 return NULL;
7728 if (!_PyVerify_fd(fd))
7729 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 if (fd < 0)
7732 return posix_error();
7733 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007734}
7735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007736
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007737PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007738"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007739Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007740
Barry Warsaw53699e91996-12-10 23:23:01 +00007741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007742posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007743{
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 int fd, fd2, res;
7745 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7746 return NULL;
7747 if (!_PyVerify_fd_dup2(fd, fd2))
7748 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 if (res < 0)
7751 return posix_error();
7752 Py_INCREF(Py_None);
7753 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007754}
7755
Ross Lagerwall7807c352011-03-17 20:20:30 +02007756#ifdef HAVE_LOCKF
7757PyDoc_STRVAR(posix_lockf__doc__,
7758"lockf(fd, cmd, len)\n\n\
7759Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7760fd is an open file descriptor.\n\
7761cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7762F_TEST.\n\
7763len specifies the section of the file to lock.");
7764
7765static PyObject *
7766posix_lockf(PyObject *self, PyObject *args)
7767{
7768 int fd, cmd, res;
7769 off_t len;
7770 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7771 &fd, &cmd, _parse_off_t, &len))
7772 return NULL;
7773
7774 Py_BEGIN_ALLOW_THREADS
7775 res = lockf(fd, cmd, len);
7776 Py_END_ALLOW_THREADS
7777
7778 if (res < 0)
7779 return posix_error();
7780
7781 Py_RETURN_NONE;
7782}
7783#endif
7784
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007785
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007786PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007787"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007788Set the current position of a file descriptor.\n\
7789Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007790
Barry Warsaw53699e91996-12-10 23:23:01 +00007791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007792posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007793{
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007795#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007797#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007799#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007800 PyObject *posobj;
7801 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007803#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7805 switch (how) {
7806 case 0: how = SEEK_SET; break;
7807 case 1: how = SEEK_CUR; break;
7808 case 2: how = SEEK_END; break;
7809 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007810#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007811
Ross Lagerwall8e749672011-03-17 21:54:07 +02007812#if !defined(HAVE_LARGEFILE_SUPPORT)
7813 pos = PyLong_AsLong(posobj);
7814#else
7815 pos = PyLong_AsLongLong(posobj);
7816#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 if (PyErr_Occurred())
7818 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007819
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 if (!_PyVerify_fd(fd))
7821 return posix_error();
7822 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007823#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007825#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007827#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 Py_END_ALLOW_THREADS
7829 if (res < 0)
7830 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007831
7832#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007834#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007836#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007837}
7838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007839
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007840PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007841"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007842Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007843
Barry Warsaw53699e91996-12-10 23:23:01 +00007844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007845posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007846{
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 int fd, size;
7848 Py_ssize_t n;
7849 PyObject *buffer;
7850 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7851 return NULL;
7852 if (size < 0) {
7853 errno = EINVAL;
7854 return posix_error();
7855 }
7856 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7857 if (buffer == NULL)
7858 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007859 if (!_PyVerify_fd(fd)) {
7860 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007862 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 Py_BEGIN_ALLOW_THREADS
7864 n = read(fd, PyBytes_AS_STRING(buffer), size);
7865 Py_END_ALLOW_THREADS
7866 if (n < 0) {
7867 Py_DECREF(buffer);
7868 return posix_error();
7869 }
7870 if (n != size)
7871 _PyBytes_Resize(&buffer, n);
7872 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007873}
7874
Ross Lagerwall7807c352011-03-17 20:20:30 +02007875#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7876 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007877static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007878iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7879{
7880 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007881 Py_ssize_t blen, total = 0;
7882
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007883 *iov = PyMem_New(struct iovec, cnt);
7884 if (*iov == NULL) {
7885 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007886 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007887 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007888
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007889 *buf = PyMem_New(Py_buffer, cnt);
7890 if (*buf == NULL) {
7891 PyMem_Del(*iov);
7892 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007893 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007894 }
7895
7896 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007897 PyObject *item = PySequence_GetItem(seq, i);
7898 if (item == NULL)
7899 goto fail;
7900 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7901 Py_DECREF(item);
7902 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007903 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007904 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007905 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007906 blen = (*buf)[i].len;
7907 (*iov)[i].iov_len = blen;
7908 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007909 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007910 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007911
7912fail:
7913 PyMem_Del(*iov);
7914 for (j = 0; j < i; j++) {
7915 PyBuffer_Release(&(*buf)[j]);
7916 }
7917 PyMem_Del(*buf);
7918 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007919}
7920
7921static void
7922iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7923{
7924 int i;
7925 PyMem_Del(iov);
7926 for (i = 0; i < cnt; i++) {
7927 PyBuffer_Release(&buf[i]);
7928 }
7929 PyMem_Del(buf);
7930}
7931#endif
7932
Ross Lagerwall7807c352011-03-17 20:20:30 +02007933#ifdef HAVE_READV
7934PyDoc_STRVAR(posix_readv__doc__,
7935"readv(fd, buffers) -> bytesread\n\n\
7936Read from a file descriptor into a number of writable buffers. buffers\n\
7937is an arbitrary sequence of writable buffers.\n\
7938Returns the total number of bytes read.");
7939
7940static PyObject *
7941posix_readv(PyObject *self, PyObject *args)
7942{
7943 int fd, cnt;
7944 Py_ssize_t n;
7945 PyObject *seq;
7946 struct iovec *iov;
7947 Py_buffer *buf;
7948
7949 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7950 return NULL;
7951 if (!PySequence_Check(seq)) {
7952 PyErr_SetString(PyExc_TypeError,
7953 "readv() arg 2 must be a sequence");
7954 return NULL;
7955 }
7956 cnt = PySequence_Size(seq);
7957
7958 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7959 return NULL;
7960
7961 Py_BEGIN_ALLOW_THREADS
7962 n = readv(fd, iov, cnt);
7963 Py_END_ALLOW_THREADS
7964
7965 iov_cleanup(iov, buf, cnt);
7966 return PyLong_FromSsize_t(n);
7967}
7968#endif
7969
7970#ifdef HAVE_PREAD
7971PyDoc_STRVAR(posix_pread__doc__,
7972"pread(fd, buffersize, offset) -> string\n\n\
7973Read from a file descriptor, fd, at a position of offset. It will read up\n\
7974to buffersize number of bytes. The file offset remains unchanged.");
7975
7976static PyObject *
7977posix_pread(PyObject *self, PyObject *args)
7978{
7979 int fd, size;
7980 off_t offset;
7981 Py_ssize_t n;
7982 PyObject *buffer;
7983 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7984 return NULL;
7985
7986 if (size < 0) {
7987 errno = EINVAL;
7988 return posix_error();
7989 }
7990 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7991 if (buffer == NULL)
7992 return NULL;
7993 if (!_PyVerify_fd(fd)) {
7994 Py_DECREF(buffer);
7995 return posix_error();
7996 }
7997 Py_BEGIN_ALLOW_THREADS
7998 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7999 Py_END_ALLOW_THREADS
8000 if (n < 0) {
8001 Py_DECREF(buffer);
8002 return posix_error();
8003 }
8004 if (n != size)
8005 _PyBytes_Resize(&buffer, n);
8006 return buffer;
8007}
8008#endif
8009
8010PyDoc_STRVAR(posix_write__doc__,
8011"write(fd, string) -> byteswritten\n\n\
8012Write a string to a file descriptor.");
8013
8014static PyObject *
8015posix_write(PyObject *self, PyObject *args)
8016{
8017 Py_buffer pbuf;
8018 int fd;
8019 Py_ssize_t size, len;
8020
8021 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8022 return NULL;
8023 if (!_PyVerify_fd(fd)) {
8024 PyBuffer_Release(&pbuf);
8025 return posix_error();
8026 }
8027 len = pbuf.len;
8028 Py_BEGIN_ALLOW_THREADS
8029#if defined(MS_WIN64) || defined(MS_WINDOWS)
8030 if (len > INT_MAX)
8031 len = INT_MAX;
8032 size = write(fd, pbuf.buf, (int)len);
8033#else
8034 size = write(fd, pbuf.buf, len);
8035#endif
8036 Py_END_ALLOW_THREADS
8037 PyBuffer_Release(&pbuf);
8038 if (size < 0)
8039 return posix_error();
8040 return PyLong_FromSsize_t(size);
8041}
8042
8043#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008044PyDoc_STRVAR(posix_sendfile__doc__,
8045"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8046sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8047 -> byteswritten\n\
8048Copy nbytes bytes from file descriptor in to file descriptor out.");
8049
8050static PyObject *
8051posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8052{
8053 int in, out;
8054 Py_ssize_t ret;
8055 off_t offset;
8056
8057#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8058#ifndef __APPLE__
8059 Py_ssize_t len;
8060#endif
8061 PyObject *headers = NULL, *trailers = NULL;
8062 Py_buffer *hbuf, *tbuf;
8063 off_t sbytes;
8064 struct sf_hdtr sf;
8065 int flags = 0;
8066 sf.headers = NULL;
8067 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008068 static char *keywords[] = {"out", "in",
8069 "offset", "count",
8070 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071
8072#ifdef __APPLE__
8073 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008074 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075#else
8076 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008077 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008078#endif
8079 &headers, &trailers, &flags))
8080 return NULL;
8081 if (headers != NULL) {
8082 if (!PySequence_Check(headers)) {
8083 PyErr_SetString(PyExc_TypeError,
8084 "sendfile() headers must be a sequence or None");
8085 return NULL;
8086 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008087 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008088 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008089 if (sf.hdr_cnt > 0 &&
8090 !(i = iov_setup(&(sf.headers), &hbuf,
8091 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008092 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008093#ifdef __APPLE__
8094 sbytes += i;
8095#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008096 }
8097 }
8098 if (trailers != NULL) {
8099 if (!PySequence_Check(trailers)) {
8100 PyErr_SetString(PyExc_TypeError,
8101 "sendfile() trailers must be a sequence or None");
8102 return NULL;
8103 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008104 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008105 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008106 if (sf.trl_cnt > 0 &&
8107 !(i = iov_setup(&(sf.trailers), &tbuf,
8108 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008109 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008110#ifdef __APPLE__
8111 sbytes += i;
8112#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008113 }
8114 }
8115
8116 Py_BEGIN_ALLOW_THREADS
8117#ifdef __APPLE__
8118 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8119#else
8120 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8121#endif
8122 Py_END_ALLOW_THREADS
8123
8124 if (sf.headers != NULL)
8125 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8126 if (sf.trailers != NULL)
8127 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8128
8129 if (ret < 0) {
8130 if ((errno == EAGAIN) || (errno == EBUSY)) {
8131 if (sbytes != 0) {
8132 // some data has been sent
8133 goto done;
8134 }
8135 else {
8136 // no data has been sent; upper application is supposed
8137 // to retry on EAGAIN or EBUSY
8138 return posix_error();
8139 }
8140 }
8141 return posix_error();
8142 }
8143 goto done;
8144
8145done:
8146 #if !defined(HAVE_LARGEFILE_SUPPORT)
8147 return Py_BuildValue("l", sbytes);
8148 #else
8149 return Py_BuildValue("L", sbytes);
8150 #endif
8151
8152#else
8153 Py_ssize_t count;
8154 PyObject *offobj;
8155 static char *keywords[] = {"out", "in",
8156 "offset", "count", NULL};
8157 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8158 keywords, &out, &in, &offobj, &count))
8159 return NULL;
8160#ifdef linux
8161 if (offobj == Py_None) {
8162 Py_BEGIN_ALLOW_THREADS
8163 ret = sendfile(out, in, NULL, count);
8164 Py_END_ALLOW_THREADS
8165 if (ret < 0)
8166 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008167 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008168 }
8169#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008170 if (!_parse_off_t(offobj, &offset))
8171 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008172 Py_BEGIN_ALLOW_THREADS
8173 ret = sendfile(out, in, &offset, count);
8174 Py_END_ALLOW_THREADS
8175 if (ret < 0)
8176 return posix_error();
8177 return Py_BuildValue("n", ret);
8178#endif
8179}
8180#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008181
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008182PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008183"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008184Like stat(), but for an open file descriptor.\n\
8185Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008186
Barry Warsaw53699e91996-12-10 23:23:01 +00008187static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008188posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008189{
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 int fd;
8191 STRUCT_STAT st;
8192 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008193 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008195#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008196 /* on OpenVMS we must ensure that all bytes are written to the file */
8197 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008198#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 Py_BEGIN_ALLOW_THREADS
8200 res = FSTAT(fd, &st);
8201 Py_END_ALLOW_THREADS
8202 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008203#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008204 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008205#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008206 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008207#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 }
Tim Peters5aa91602002-01-30 05:46:57 +00008209
Victor Stinner4195b5c2012-02-08 23:03:19 +01008210 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008211}
8212
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008213PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008214"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008215Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008216connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008217
8218static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008219posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008220{
Victor Stinner8c62be82010-05-06 00:08:46 +00008221 int fd;
8222 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8223 return NULL;
8224 if (!_PyVerify_fd(fd))
8225 return PyBool_FromLong(0);
8226 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008227}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008228
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008229#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008230PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008231"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008232Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008233
Barry Warsaw53699e91996-12-10 23:23:01 +00008234static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008235posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008236{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008237#if defined(PYOS_OS2)
8238 HFILE read, write;
8239 APIRET rc;
8240
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008241 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008242 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008243 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008244
8245 return Py_BuildValue("(ii)", read, write);
8246#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008247#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 int fds[2];
8249 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008250 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008251 if (res != 0)
8252 return posix_error();
8253 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008254#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008255 HANDLE read, write;
8256 int read_fd, write_fd;
8257 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008258 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008259 if (!ok)
8260 return win32_error("CreatePipe", NULL);
8261 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8262 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8263 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008264#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008265#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008266}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008267#endif /* HAVE_PIPE */
8268
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008269#ifdef HAVE_PIPE2
8270PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008271"pipe2(flags) -> (read_end, write_end)\n\n\
8272Create a pipe with flags set atomically.\n\
8273flags can be constructed by ORing together one or more of these values:\n\
8274O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008275");
8276
8277static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008278posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008279{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008280 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008281 int fds[2];
8282 int res;
8283
Serhiy Storchaka9101e232013-01-19 12:41:45 +02008284 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008285 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008286 return NULL;
8287
8288 res = pipe2(fds, flags);
8289 if (res != 0)
8290 return posix_error();
8291 return Py_BuildValue("(ii)", fds[0], fds[1]);
8292}
8293#endif /* HAVE_PIPE2 */
8294
Ross Lagerwall7807c352011-03-17 20:20:30 +02008295#ifdef HAVE_WRITEV
8296PyDoc_STRVAR(posix_writev__doc__,
8297"writev(fd, buffers) -> byteswritten\n\n\
8298Write the contents of buffers to a file descriptor, where buffers is an\n\
8299arbitrary sequence of buffers.\n\
8300Returns the total bytes written.");
8301
8302static PyObject *
8303posix_writev(PyObject *self, PyObject *args)
8304{
8305 int fd, cnt;
8306 Py_ssize_t res;
8307 PyObject *seq;
8308 struct iovec *iov;
8309 Py_buffer *buf;
8310 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8311 return NULL;
8312 if (!PySequence_Check(seq)) {
8313 PyErr_SetString(PyExc_TypeError,
8314 "writev() arg 2 must be a sequence");
8315 return NULL;
8316 }
8317 cnt = PySequence_Size(seq);
8318
8319 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8320 return NULL;
8321 }
8322
8323 Py_BEGIN_ALLOW_THREADS
8324 res = writev(fd, iov, cnt);
8325 Py_END_ALLOW_THREADS
8326
8327 iov_cleanup(iov, buf, cnt);
8328 return PyLong_FromSsize_t(res);
8329}
8330#endif
8331
8332#ifdef HAVE_PWRITE
8333PyDoc_STRVAR(posix_pwrite__doc__,
8334"pwrite(fd, string, offset) -> byteswritten\n\n\
8335Write string to a file descriptor, fd, from offset, leaving the file\n\
8336offset unchanged.");
8337
8338static PyObject *
8339posix_pwrite(PyObject *self, PyObject *args)
8340{
8341 Py_buffer pbuf;
8342 int fd;
8343 off_t offset;
8344 Py_ssize_t size;
8345
8346 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8347 return NULL;
8348
8349 if (!_PyVerify_fd(fd)) {
8350 PyBuffer_Release(&pbuf);
8351 return posix_error();
8352 }
8353 Py_BEGIN_ALLOW_THREADS
8354 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8355 Py_END_ALLOW_THREADS
8356 PyBuffer_Release(&pbuf);
8357 if (size < 0)
8358 return posix_error();
8359 return PyLong_FromSsize_t(size);
8360}
8361#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008362
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008363#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008364PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008365"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8366Create a FIFO (a POSIX named pipe).\n\
8367\n\
8368If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8369 and path should be relative; path will then be relative to that directory.\n\
8370dir_fd may not be implemented on your platform.\n\
8371 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008372
Barry Warsaw53699e91996-12-10 23:23:01 +00008373static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008374posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008375{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008376 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008377 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008378 int dir_fd = DEFAULT_DIR_FD;
8379 int result;
8380 PyObject *return_value = NULL;
8381 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8382
8383 memset(&path, 0, sizeof(path));
8384 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8385 path_converter, &path,
8386 &mode,
8387#ifdef HAVE_MKFIFOAT
8388 dir_fd_converter, &dir_fd
8389#else
8390 dir_fd_unavailable, &dir_fd
8391#endif
8392 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008393 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008394
Victor Stinner8c62be82010-05-06 00:08:46 +00008395 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008396#ifdef HAVE_MKFIFOAT
8397 if (dir_fd != DEFAULT_DIR_FD)
8398 result = mkfifoat(dir_fd, path.narrow, mode);
8399 else
8400#endif
8401 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008403
8404 if (result < 0) {
8405 return_value = posix_error();
8406 goto exit;
8407 }
8408
8409 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008411
8412exit:
8413 path_cleanup(&path);
8414 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008415}
8416#endif
8417
Neal Norwitz11690112002-07-30 01:08:28 +00008418#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008419PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008420"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008421Create a filesystem node (file, device special file or named pipe)\n\
8422named filename. mode specifies both the permissions to use and the\n\
8423type of node to be created, being combined (bitwise OR) with one of\n\
8424S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008425device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008426os.makedev()), otherwise it is ignored.\n\
8427\n\
8428If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8429 and path should be relative; path will then be relative to that directory.\n\
8430dir_fd may not be implemented on your platform.\n\
8431 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008432
8433
8434static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008435posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008436{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008437 path_t path;
8438 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008440 int dir_fd = DEFAULT_DIR_FD;
8441 int result;
8442 PyObject *return_value = NULL;
8443 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8444
8445 memset(&path, 0, sizeof(path));
8446 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8447 path_converter, &path,
8448 &mode, &device,
8449#ifdef HAVE_MKNODAT
8450 dir_fd_converter, &dir_fd
8451#else
8452 dir_fd_unavailable, &dir_fd
8453#endif
8454 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008456
Victor Stinner8c62be82010-05-06 00:08:46 +00008457 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008458#ifdef HAVE_MKNODAT
8459 if (dir_fd != DEFAULT_DIR_FD)
8460 result = mknodat(dir_fd, path.narrow, mode, device);
8461 else
8462#endif
8463 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008465
8466 if (result < 0) {
8467 return_value = posix_error();
8468 goto exit;
8469 }
8470
8471 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008473
Larry Hastings9cf065c2012-06-22 16:30:09 -07008474exit:
8475 path_cleanup(&path);
8476 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008477}
8478#endif
8479
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008480#ifdef HAVE_DEVICE_MACROS
8481PyDoc_STRVAR(posix_major__doc__,
8482"major(device) -> major number\n\
8483Extracts a device major number from a raw device number.");
8484
8485static PyObject *
8486posix_major(PyObject *self, PyObject *args)
8487{
Victor Stinner8c62be82010-05-06 00:08:46 +00008488 int device;
8489 if (!PyArg_ParseTuple(args, "i:major", &device))
8490 return NULL;
8491 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008492}
8493
8494PyDoc_STRVAR(posix_minor__doc__,
8495"minor(device) -> minor number\n\
8496Extracts a device minor number from a raw device number.");
8497
8498static PyObject *
8499posix_minor(PyObject *self, PyObject *args)
8500{
Victor Stinner8c62be82010-05-06 00:08:46 +00008501 int device;
8502 if (!PyArg_ParseTuple(args, "i:minor", &device))
8503 return NULL;
8504 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008505}
8506
8507PyDoc_STRVAR(posix_makedev__doc__,
8508"makedev(major, minor) -> device number\n\
8509Composes a raw device number from the major and minor device numbers.");
8510
8511static PyObject *
8512posix_makedev(PyObject *self, PyObject *args)
8513{
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 int major, minor;
8515 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8516 return NULL;
8517 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008518}
8519#endif /* device macros */
8520
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008521
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008522#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008523PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008524"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008525Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008526
Barry Warsaw53699e91996-12-10 23:23:01 +00008527static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008528posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008529{
Victor Stinner8c62be82010-05-06 00:08:46 +00008530 int fd;
8531 off_t length;
8532 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008533
Ross Lagerwall7807c352011-03-17 20:20:30 +02008534 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008536
Victor Stinner8c62be82010-05-06 00:08:46 +00008537 Py_BEGIN_ALLOW_THREADS
8538 res = ftruncate(fd, length);
8539 Py_END_ALLOW_THREADS
8540 if (res < 0)
8541 return posix_error();
8542 Py_INCREF(Py_None);
8543 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008544}
8545#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008546
Ross Lagerwall7807c352011-03-17 20:20:30 +02008547#ifdef HAVE_TRUNCATE
8548PyDoc_STRVAR(posix_truncate__doc__,
8549"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008550Truncate the file given by path to length bytes.\n\
8551On some platforms, path may also be specified as an open file descriptor.\n\
8552 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008553
8554static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008555posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008556{
Georg Brandl306336b2012-06-24 12:55:33 +02008557 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008558 off_t length;
8559 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008560 PyObject *result = NULL;
8561 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008562
Georg Brandl306336b2012-06-24 12:55:33 +02008563 memset(&path, 0, sizeof(path));
8564#ifdef HAVE_FTRUNCATE
8565 path.allow_fd = 1;
8566#endif
8567 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8568 path_converter, &path,
8569 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008570 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008571
8572 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008573#ifdef HAVE_FTRUNCATE
8574 if (path.fd != -1)
8575 res = ftruncate(path.fd, length);
8576 else
8577#endif
8578 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008579 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008580 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008581 result = path_posix_error("truncate", &path);
8582 else {
8583 Py_INCREF(Py_None);
8584 result = Py_None;
8585 }
8586 path_cleanup(&path);
8587 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008588}
8589#endif
8590
8591#ifdef HAVE_POSIX_FALLOCATE
8592PyDoc_STRVAR(posix_posix_fallocate__doc__,
8593"posix_fallocate(fd, offset, len)\n\n\
8594Ensures that enough disk space is allocated for the file specified by fd\n\
8595starting from offset and continuing for len bytes.");
8596
8597static PyObject *
8598posix_posix_fallocate(PyObject *self, PyObject *args)
8599{
8600 off_t len, offset;
8601 int res, fd;
8602
8603 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8604 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8605 return NULL;
8606
8607 Py_BEGIN_ALLOW_THREADS
8608 res = posix_fallocate(fd, offset, len);
8609 Py_END_ALLOW_THREADS
8610 if (res != 0) {
8611 errno = res;
8612 return posix_error();
8613 }
8614 Py_RETURN_NONE;
8615}
8616#endif
8617
8618#ifdef HAVE_POSIX_FADVISE
8619PyDoc_STRVAR(posix_posix_fadvise__doc__,
8620"posix_fadvise(fd, offset, len, advice)\n\n\
8621Announces an intention to access data in a specific pattern thus allowing\n\
8622the kernel to make optimizations.\n\
8623The advice applies to the region of the file specified by fd starting at\n\
8624offset and continuing for len bytes.\n\
8625advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8626POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8627POSIX_FADV_DONTNEED.");
8628
8629static PyObject *
8630posix_posix_fadvise(PyObject *self, PyObject *args)
8631{
8632 off_t len, offset;
8633 int res, fd, advice;
8634
8635 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8636 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8637 return NULL;
8638
8639 Py_BEGIN_ALLOW_THREADS
8640 res = posix_fadvise(fd, offset, len, advice);
8641 Py_END_ALLOW_THREADS
8642 if (res != 0) {
8643 errno = res;
8644 return posix_error();
8645 }
8646 Py_RETURN_NONE;
8647}
8648#endif
8649
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008650#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008651PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008652"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008653Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008654
Fred Drake762e2061999-08-26 17:23:54 +00008655/* Save putenv() parameters as values here, so we can collect them when they
8656 * get re-set with another call for the same key. */
8657static PyObject *posix_putenv_garbage;
8658
Tim Peters5aa91602002-01-30 05:46:57 +00008659static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008660posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008661{
Victor Stinner84ae1182010-05-06 22:05:07 +00008662 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008663#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008664 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008665 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008666
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008668 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008669 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008671
Victor Stinner65170952011-11-22 22:16:17 +01008672 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008673 if (newstr == NULL) {
8674 PyErr_NoMemory();
8675 goto error;
8676 }
Victor Stinner65170952011-11-22 22:16:17 +01008677 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8678 PyErr_Format(PyExc_ValueError,
8679 "the environment variable is longer than %u characters",
8680 _MAX_ENV);
8681 goto error;
8682 }
8683
Victor Stinner8c62be82010-05-06 00:08:46 +00008684 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008685 if (newenv == NULL)
8686 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008687 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008689 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008690 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008691#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008692 PyObject *os1, *os2;
8693 char *s1, *s2;
8694 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008695
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008696 if (!PyArg_ParseTuple(args,
8697 "O&O&:putenv",
8698 PyUnicode_FSConverter, &os1,
8699 PyUnicode_FSConverter, &os2))
8700 return NULL;
8701 s1 = PyBytes_AsString(os1);
8702 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008703
Victor Stinner65170952011-11-22 22:16:17 +01008704 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008705 if (newstr == NULL) {
8706 PyErr_NoMemory();
8707 goto error;
8708 }
8709
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008713 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008714 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008715#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008716
Victor Stinner8c62be82010-05-06 00:08:46 +00008717 /* Install the first arg and newstr in posix_putenv_garbage;
8718 * this will cause previous value to be collected. This has to
8719 * happen after the real putenv() call because the old value
8720 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008721 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008722 /* really not much we can do; just leak */
8723 PyErr_Clear();
8724 }
8725 else {
8726 Py_DECREF(newstr);
8727 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008728
Martin v. Löwis011e8422009-05-05 04:43:17 +00008729#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 Py_DECREF(os1);
8731 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008732#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008733 Py_RETURN_NONE;
8734
8735error:
8736#ifndef MS_WINDOWS
8737 Py_DECREF(os1);
8738 Py_DECREF(os2);
8739#endif
8740 Py_XDECREF(newstr);
8741 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008742}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008743#endif /* putenv */
8744
Guido van Rossumc524d952001-10-19 01:31:59 +00008745#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008746PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008747"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008748Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008749
8750static PyObject *
8751posix_unsetenv(PyObject *self, PyObject *args)
8752{
Victor Stinner65170952011-11-22 22:16:17 +01008753 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008754#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008755 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008756#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008757
8758 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008759
Victor Stinner65170952011-11-22 22:16:17 +01008760 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008761 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008762
Victor Stinner984890f2011-11-24 13:53:38 +01008763#ifdef HAVE_BROKEN_UNSETENV
8764 unsetenv(PyBytes_AS_STRING(name));
8765#else
Victor Stinner65170952011-11-22 22:16:17 +01008766 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008767 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008768 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008769 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008770 }
Victor Stinner984890f2011-11-24 13:53:38 +01008771#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008772
Victor Stinner8c62be82010-05-06 00:08:46 +00008773 /* Remove the key from posix_putenv_garbage;
8774 * this will cause it to be collected. This has to
8775 * happen after the real unsetenv() call because the
8776 * old value was still accessible until then.
8777 */
Victor Stinner65170952011-11-22 22:16:17 +01008778 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008779 /* really not much we can do; just leak */
8780 PyErr_Clear();
8781 }
Victor Stinner65170952011-11-22 22:16:17 +01008782 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008783 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008784}
8785#endif /* unsetenv */
8786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008787PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008788"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008789Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008790
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008792posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008793{
Victor Stinner8c62be82010-05-06 00:08:46 +00008794 int code;
8795 char *message;
8796 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8797 return NULL;
8798 message = strerror(code);
8799 if (message == NULL) {
8800 PyErr_SetString(PyExc_ValueError,
8801 "strerror() argument out of range");
8802 return NULL;
8803 }
Victor Stinner1b579672011-12-17 05:47:23 +01008804 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008805}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008806
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008807
Guido van Rossumc9641791998-08-04 15:26:23 +00008808#ifdef HAVE_SYS_WAIT_H
8809
Fred Drake106c1a02002-04-23 15:58:02 +00008810#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008811PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008812"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008813Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008814
8815static PyObject *
8816posix_WCOREDUMP(PyObject *self, PyObject *args)
8817{
Victor Stinner8c62be82010-05-06 00:08:46 +00008818 WAIT_TYPE status;
8819 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008820
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8822 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008823
Victor Stinner8c62be82010-05-06 00:08:46 +00008824 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008825}
8826#endif /* WCOREDUMP */
8827
8828#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008829PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008830"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008831Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008832job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008833
8834static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008835posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008836{
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 WAIT_TYPE status;
8838 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008839
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8841 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008842
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008844}
8845#endif /* WIFCONTINUED */
8846
Guido van Rossumc9641791998-08-04 15:26:23 +00008847#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008848PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008849"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008850Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008851
8852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008853posix_WIFSTOPPED(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:WIFSTOPPED", &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(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008862}
8863#endif /* WIFSTOPPED */
8864
8865#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008866PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008867"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008868Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008869
8870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008871posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008872{
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 WAIT_TYPE status;
8874 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008875
Victor Stinner8c62be82010-05-06 00:08:46 +00008876 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8877 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008878
Victor Stinner8c62be82010-05-06 00:08:46 +00008879 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008880}
8881#endif /* WIFSIGNALED */
8882
8883#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008884PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008885"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008886Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008887system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008888
8889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008890posix_WIFEXITED(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:WIFEXITED", &WAIT_STATUS_INT(status)))
8896 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008897
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008899}
8900#endif /* WIFEXITED */
8901
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008902#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008903PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008904"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008905Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008906
8907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008908posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008909{
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 WAIT_TYPE status;
8911 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008912
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8914 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008915
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008917}
8918#endif /* WEXITSTATUS */
8919
8920#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008921PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008922"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008923Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008924value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008925
8926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008927posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008928{
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 WAIT_TYPE status;
8930 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008931
Victor Stinner8c62be82010-05-06 00:08:46 +00008932 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8933 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008934
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008936}
8937#endif /* WTERMSIG */
8938
8939#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008940PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008941"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008942Return the signal that stopped the process that provided\n\
8943the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008944
8945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008946posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008947{
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 WAIT_TYPE status;
8949 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008950
Victor Stinner8c62be82010-05-06 00:08:46 +00008951 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8952 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008953
Victor Stinner8c62be82010-05-06 00:08:46 +00008954 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008955}
8956#endif /* WSTOPSIG */
8957
8958#endif /* HAVE_SYS_WAIT_H */
8959
8960
Thomas Wouters477c8d52006-05-27 19:21:47 +00008961#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008962#ifdef _SCO_DS
8963/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8964 needed definitions in sys/statvfs.h */
8965#define _SVID3
8966#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008967#include <sys/statvfs.h>
8968
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008969static PyObject*
8970_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008971 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8972 if (v == NULL)
8973 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008974
8975#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8977 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8978 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8979 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8980 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8981 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8982 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8983 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8984 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8985 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008986#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008987 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8988 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8989 PyStructSequence_SET_ITEM(v, 2,
8990 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8991 PyStructSequence_SET_ITEM(v, 3,
8992 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8993 PyStructSequence_SET_ITEM(v, 4,
8994 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8995 PyStructSequence_SET_ITEM(v, 5,
8996 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8997 PyStructSequence_SET_ITEM(v, 6,
8998 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8999 PyStructSequence_SET_ITEM(v, 7,
9000 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9001 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9002 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009003#endif
9004
Victor Stinner8c62be82010-05-06 00:08:46 +00009005 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009006}
9007
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009008PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009009"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009010Perform an fstatvfs system call on the given fd.\n\
9011Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009012
9013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009014posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009015{
Victor Stinner8c62be82010-05-06 00:08:46 +00009016 int fd, res;
9017 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009018
Victor Stinner8c62be82010-05-06 00:08:46 +00009019 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9020 return NULL;
9021 Py_BEGIN_ALLOW_THREADS
9022 res = fstatvfs(fd, &st);
9023 Py_END_ALLOW_THREADS
9024 if (res != 0)
9025 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009026
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009028}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009029#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009030
9031
Thomas Wouters477c8d52006-05-27 19:21:47 +00009032#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009033#include <sys/statvfs.h>
9034
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009035PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009036"statvfs(path)\n\n\
9037Perform a statvfs system call on the given path.\n\
9038\n\
9039path may always be specified as a string.\n\
9040On some platforms, path may also be specified as an open file descriptor.\n\
9041 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009042
9043static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009044posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009045{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009046 static char *keywords[] = {"path", NULL};
9047 path_t path;
9048 int result;
9049 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009050 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009051
Larry Hastings9cf065c2012-06-22 16:30:09 -07009052 memset(&path, 0, sizeof(path));
9053#ifdef HAVE_FSTATVFS
9054 path.allow_fd = 1;
9055#endif
9056 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9057 path_converter, &path
9058 ))
9059 return NULL;
9060
9061 Py_BEGIN_ALLOW_THREADS
9062#ifdef HAVE_FSTATVFS
9063 if (path.fd != -1) {
9064#ifdef __APPLE__
9065 /* handle weak-linking on Mac OS X 10.3 */
9066 if (fstatvfs == NULL) {
9067 fd_specified("statvfs", path.fd);
9068 goto exit;
9069 }
9070#endif
9071 result = fstatvfs(path.fd, &st);
9072 }
9073 else
9074#endif
9075 result = statvfs(path.narrow, &st);
9076 Py_END_ALLOW_THREADS
9077
9078 if (result) {
9079 return_value = path_posix_error("statvfs", &path);
9080 goto exit;
9081 }
9082
9083 return_value = _pystatvfs_fromstructstatvfs(st);
9084
9085exit:
9086 path_cleanup(&path);
9087 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009088}
9089#endif /* HAVE_STATVFS */
9090
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009091#ifdef MS_WINDOWS
9092PyDoc_STRVAR(win32__getdiskusage__doc__,
9093"_getdiskusage(path) -> (total, free)\n\n\
9094Return disk usage statistics about the given path as (total, free) tuple.");
9095
9096static PyObject *
9097win32__getdiskusage(PyObject *self, PyObject *args)
9098{
9099 BOOL retval;
9100 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009101 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009102
Victor Stinner6139c1b2011-11-09 22:14:14 +01009103 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009104 return NULL;
9105
9106 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009107 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009108 Py_END_ALLOW_THREADS
9109 if (retval == 0)
9110 return PyErr_SetFromWindowsErr(0);
9111
9112 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9113}
9114#endif
9115
9116
Fred Drakec9680921999-12-13 16:37:25 +00009117/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9118 * It maps strings representing configuration variable names to
9119 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009120 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009121 * rarely-used constants. There are three separate tables that use
9122 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009123 *
9124 * This code is always included, even if none of the interfaces that
9125 * need it are included. The #if hackery needed to avoid it would be
9126 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009127 */
9128struct constdef {
9129 char *name;
9130 long value;
9131};
9132
Fred Drake12c6e2d1999-12-14 21:25:03 +00009133static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009134conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009135 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009136{
Christian Heimes217cfd12007-12-02 14:31:20 +00009137 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009138 *valuep = PyLong_AS_LONG(arg);
9139 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009140 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009141 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009142 /* look up the value in the table using a binary search */
9143 size_t lo = 0;
9144 size_t mid;
9145 size_t hi = tablesize;
9146 int cmp;
9147 const char *confname;
9148 if (!PyUnicode_Check(arg)) {
9149 PyErr_SetString(PyExc_TypeError,
9150 "configuration names must be strings or integers");
9151 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009153 confname = _PyUnicode_AsString(arg);
9154 if (confname == NULL)
9155 return 0;
9156 while (lo < hi) {
9157 mid = (lo + hi) / 2;
9158 cmp = strcmp(confname, table[mid].name);
9159 if (cmp < 0)
9160 hi = mid;
9161 else if (cmp > 0)
9162 lo = mid + 1;
9163 else {
9164 *valuep = table[mid].value;
9165 return 1;
9166 }
9167 }
9168 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9169 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009170 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009171}
9172
9173
9174#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9175static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009176#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009178#endif
9179#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009181#endif
Fred Drakec9680921999-12-13 16:37:25 +00009182#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009184#endif
9185#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009187#endif
9188#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009190#endif
9191#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009193#endif
9194#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009196#endif
9197#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009199#endif
9200#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009202#endif
9203#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009205#endif
9206#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009208#endif
9209#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009210 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009211#endif
9212#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009214#endif
9215#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009217#endif
9218#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009219 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009220#endif
9221#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009222 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009223#endif
9224#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009226#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009227#ifdef _PC_ACL_ENABLED
9228 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9229#endif
9230#ifdef _PC_MIN_HOLE_SIZE
9231 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9232#endif
9233#ifdef _PC_ALLOC_SIZE_MIN
9234 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9235#endif
9236#ifdef _PC_REC_INCR_XFER_SIZE
9237 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9238#endif
9239#ifdef _PC_REC_MAX_XFER_SIZE
9240 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9241#endif
9242#ifdef _PC_REC_MIN_XFER_SIZE
9243 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9244#endif
9245#ifdef _PC_REC_XFER_ALIGN
9246 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9247#endif
9248#ifdef _PC_SYMLINK_MAX
9249 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9250#endif
9251#ifdef _PC_XATTR_ENABLED
9252 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9253#endif
9254#ifdef _PC_XATTR_EXISTS
9255 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9256#endif
9257#ifdef _PC_TIMESTAMP_RESOLUTION
9258 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9259#endif
Fred Drakec9680921999-12-13 16:37:25 +00009260};
9261
Fred Drakec9680921999-12-13 16:37:25 +00009262static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009263conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009264{
9265 return conv_confname(arg, valuep, posix_constants_pathconf,
9266 sizeof(posix_constants_pathconf)
9267 / sizeof(struct constdef));
9268}
9269#endif
9270
9271#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009272PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009273"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009274Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009275If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009276
9277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009278posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009279{
9280 PyObject *result = NULL;
9281 int name, fd;
9282
Fred Drake12c6e2d1999-12-14 21:25:03 +00009283 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9284 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009285 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009286
Stefan Krah0e803b32010-11-26 16:16:47 +00009287 errno = 0;
9288 limit = fpathconf(fd, name);
9289 if (limit == -1 && errno != 0)
9290 posix_error();
9291 else
9292 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009293 }
9294 return result;
9295}
9296#endif
9297
9298
9299#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009300PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009301"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009302Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009303If there is no limit, return -1.\n\
9304On some platforms, path may also be specified as an open file descriptor.\n\
9305 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009306
9307static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009308posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009309{
Georg Brandl306336b2012-06-24 12:55:33 +02009310 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009311 PyObject *result = NULL;
9312 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009313 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009314
Georg Brandl306336b2012-06-24 12:55:33 +02009315 memset(&path, 0, sizeof(path));
9316#ifdef HAVE_FPATHCONF
9317 path.allow_fd = 1;
9318#endif
9319 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9320 path_converter, &path,
9321 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009323
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009325#ifdef HAVE_FPATHCONF
9326 if (path.fd != -1)
9327 limit = fpathconf(path.fd, name);
9328 else
9329#endif
9330 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 if (limit == -1 && errno != 0) {
9332 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009333 /* could be a path or name problem */
9334 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009335 else
Georg Brandl306336b2012-06-24 12:55:33 +02009336 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 }
9338 else
9339 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009340 }
Georg Brandl306336b2012-06-24 12:55:33 +02009341 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009342 return result;
9343}
9344#endif
9345
9346#ifdef HAVE_CONFSTR
9347static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009348#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009350#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009351#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009353#endif
9354#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009356#endif
Fred Draked86ed291999-12-15 15:34:33 +00009357#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009359#endif
9360#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009362#endif
9363#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009365#endif
9366#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009368#endif
Fred Drakec9680921999-12-13 16:37:25 +00009369#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
9387#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009389#endif
9390#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
Fred Draked86ed291999-12-15 15:34:33 +00009393#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009395#endif
Fred Drakec9680921999-12-13 16:37:25 +00009396#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009398#endif
Fred Draked86ed291999-12-15 15:34:33 +00009399#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009401#endif
9402#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009404#endif
9405#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009407#endif
9408#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009410#endif
Fred Drakec9680921999-12-13 16:37:25 +00009411#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009413#endif
9414#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009416#endif
9417#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009419#endif
9420#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009422#endif
9423#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009425#endif
9426#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009428#endif
9429#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009431#endif
9432#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009434#endif
9435#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009437#endif
9438#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009440#endif
9441#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009443#endif
9444#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009446#endif
9447#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009449#endif
9450#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009452#endif
9453#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009455#endif
9456#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009458#endif
Fred Draked86ed291999-12-15 15:34:33 +00009459#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009461#endif
9462#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009464#endif
9465#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009467#endif
9468#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009470#endif
9471#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009473#endif
9474#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009476#endif
9477#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009479#endif
9480#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009482#endif
9483#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009485#endif
9486#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009488#endif
9489#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009491#endif
9492#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009493 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009494#endif
9495#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009497#endif
Fred Drakec9680921999-12-13 16:37:25 +00009498};
9499
9500static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009501conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009502{
9503 return conv_confname(arg, valuep, posix_constants_confstr,
9504 sizeof(posix_constants_confstr)
9505 / sizeof(struct constdef));
9506}
9507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009508PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009509"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009510Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009511
9512static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009513posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009514{
9515 PyObject *result = NULL;
9516 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009517 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009518 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009519
Victor Stinnercb043522010-09-10 23:49:04 +00009520 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9521 return NULL;
9522
9523 errno = 0;
9524 len = confstr(name, buffer, sizeof(buffer));
9525 if (len == 0) {
9526 if (errno) {
9527 posix_error();
9528 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009529 }
9530 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009531 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009532 }
9533 }
Victor Stinnercb043522010-09-10 23:49:04 +00009534
9535 if ((unsigned int)len >= sizeof(buffer)) {
9536 char *buf = PyMem_Malloc(len);
9537 if (buf == NULL)
9538 return PyErr_NoMemory();
9539 confstr(name, buf, len);
9540 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9541 PyMem_Free(buf);
9542 }
9543 else
9544 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009545 return result;
9546}
9547#endif
9548
9549
9550#ifdef HAVE_SYSCONF
9551static struct constdef posix_constants_sysconf[] = {
9552#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
Fred Draked86ed291999-12-15 15:34:33 +00009582#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009584#endif
9585#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009587#endif
Fred Drakec9680921999-12-13 16:37:25 +00009588#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
Fred Drakec9680921999-12-13 16:37:25 +00009591#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
9600#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009602#endif
9603#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
Fred Draked86ed291999-12-15 15:34:33 +00009606#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009608#endif
Fred Drakec9680921999-12-13 16:37:25 +00009609#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
9618#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009620#endif
9621#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
Fred Draked86ed291999-12-15 15:34:33 +00009624#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009626#endif
Fred Drakec9680921999-12-13 16:37:25 +00009627#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
9639#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
9648#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
9654#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
9657#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
9666#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009668#endif
9669#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009671#endif
9672#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009674#endif
9675#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009677#endif
9678#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009680#endif
9681#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009683#endif
9684#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009686#endif
9687#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009689#endif
9690#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009692#endif
9693#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
Fred Draked86ed291999-12-15 15:34:33 +00009696#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009698#endif
Fred Drakec9680921999-12-13 16:37:25 +00009699#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009701#endif
9702#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009704#endif
9705#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
Fred Draked86ed291999-12-15 15:34:33 +00009708#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009710#endif
Fred Drakec9680921999-12-13 16:37:25 +00009711#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009713#endif
Fred Draked86ed291999-12-15 15:34:33 +00009714#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009716#endif
9717#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009719#endif
Fred Drakec9680921999-12-13 16:37:25 +00009720#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
Fred Draked86ed291999-12-15 15:34:33 +00009732#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009734#endif
Fred Drakec9680921999-12-13 16:37:25 +00009735#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
Fred Draked86ed291999-12-15 15:34:33 +00009756#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009758#endif
Fred Drakec9680921999-12-13 16:37:25 +00009759#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
Fred Draked86ed291999-12-15 15:34:33 +00009765#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009767#endif
Fred Drakec9680921999-12-13 16:37:25 +00009768#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
Fred Draked86ed291999-12-15 15:34:33 +00009795#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009797#endif
9798#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009800#endif
Fred Drakec9680921999-12-13 16:37:25 +00009801#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
Fred Draked86ed291999-12-15 15:34:33 +00009906#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009908#endif
Fred Drakec9680921999-12-13 16:37:25 +00009909#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044};
10045
10046static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010047conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010048{
10049 return conv_confname(arg, valuep, posix_constants_sysconf,
10050 sizeof(posix_constants_sysconf)
10051 / sizeof(struct constdef));
10052}
10053
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010054PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010055"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010056Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010057
10058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010059posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010060{
10061 PyObject *result = NULL;
10062 int name;
10063
10064 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10065 int value;
10066
10067 errno = 0;
10068 value = sysconf(name);
10069 if (value == -1 && errno != 0)
10070 posix_error();
10071 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010072 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010073 }
10074 return result;
10075}
10076#endif
10077
10078
Fred Drakebec628d1999-12-15 18:31:10 +000010079/* This code is used to ensure that the tables of configuration value names
10080 * are in sorted order as required by conv_confname(), and also to build the
10081 * the exported dictionaries that are used to publish information about the
10082 * names available on the host platform.
10083 *
10084 * Sorting the table at runtime ensures that the table is properly ordered
10085 * when used, even for platforms we're not able to test on. It also makes
10086 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010087 */
Fred Drakebec628d1999-12-15 18:31:10 +000010088
10089static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010090cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010091{
10092 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010094 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010096
10097 return strcmp(c1->name, c2->name);
10098}
10099
10100static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010101setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010103{
Fred Drakebec628d1999-12-15 18:31:10 +000010104 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010105 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010106
10107 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10108 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010109 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010111
Barry Warsaw3155db32000-04-13 15:20:40 +000010112 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 PyObject *o = PyLong_FromLong(table[i].value);
10114 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10115 Py_XDECREF(o);
10116 Py_DECREF(d);
10117 return -1;
10118 }
10119 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010120 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010121 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010122}
10123
Fred Drakebec628d1999-12-15 18:31:10 +000010124/* Return -1 on failure, 0 on success. */
10125static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010126setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010127{
10128#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010129 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010130 sizeof(posix_constants_pathconf)
10131 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010132 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010133 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010134#endif
10135#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010136 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010137 sizeof(posix_constants_confstr)
10138 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010139 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010140 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010141#endif
10142#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010143 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010144 sizeof(posix_constants_sysconf)
10145 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010146 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010147 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010148#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010149 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010150}
Fred Draked86ed291999-12-15 15:34:33 +000010151
10152
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010153PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010154"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010155Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010156in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010157
10158static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010159posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010160{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010161 abort();
10162 /*NOTREACHED*/
10163 Py_FatalError("abort() called from Python code didn't abort!");
10164 return NULL;
10165}
Fred Drakebec628d1999-12-15 18:31:10 +000010166
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010167#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010168PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010169"startfile(filepath [, operation]) - Start a file with its associated\n\
10170application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010171\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010172When \"operation\" is not specified or \"open\", this acts like\n\
10173double-clicking the file in Explorer, or giving the file name as an\n\
10174argument to the DOS \"start\" command: the file is opened with whatever\n\
10175application (if any) its extension is associated.\n\
10176When another \"operation\" is given, it specifies what should be done with\n\
10177the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010178\n\
10179startfile returns as soon as the associated application is launched.\n\
10180There is no option to wait for the application to close, and no way\n\
10181to retrieve the application's exit status.\n\
10182\n\
10183The filepath is relative to the current directory. If you want to use\n\
10184an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010185the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010186
10187static PyObject *
10188win32_startfile(PyObject *self, PyObject *args)
10189{
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 PyObject *ofilepath;
10191 char *filepath;
10192 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010193 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010195
Victor Stinnereb5657a2011-09-30 01:44:27 +020010196 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 if (!PyArg_ParseTuple(args, "U|s:startfile",
10198 &unipath, &operation)) {
10199 PyErr_Clear();
10200 goto normal;
10201 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010202
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010204 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010206 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 PyErr_Clear();
10208 operation = NULL;
10209 goto normal;
10210 }
10211 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010212
Victor Stinnereb5657a2011-09-30 01:44:27 +020010213 wpath = PyUnicode_AsUnicode(unipath);
10214 if (wpath == NULL)
10215 goto normal;
10216 if (uoperation) {
10217 woperation = PyUnicode_AsUnicode(uoperation);
10218 if (woperation == NULL)
10219 goto normal;
10220 }
10221 else
10222 woperation = NULL;
10223
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010225 rc = ShellExecuteW((HWND)0, woperation, wpath,
10226 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 Py_END_ALLOW_THREADS
10228
Victor Stinnereb5657a2011-09-30 01:44:27 +020010229 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010231 win32_error_object("startfile", unipath);
10232 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 }
10234 Py_INCREF(Py_None);
10235 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010236
10237normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10239 PyUnicode_FSConverter, &ofilepath,
10240 &operation))
10241 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010242 if (win32_warn_bytes_api()) {
10243 Py_DECREF(ofilepath);
10244 return NULL;
10245 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 filepath = PyBytes_AsString(ofilepath);
10247 Py_BEGIN_ALLOW_THREADS
10248 rc = ShellExecute((HWND)0, operation, filepath,
10249 NULL, NULL, SW_SHOWNORMAL);
10250 Py_END_ALLOW_THREADS
10251 if (rc <= (HINSTANCE)32) {
10252 PyObject *errval = win32_error("startfile", filepath);
10253 Py_DECREF(ofilepath);
10254 return errval;
10255 }
10256 Py_DECREF(ofilepath);
10257 Py_INCREF(Py_None);
10258 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010259}
10260#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010261
Martin v. Löwis438b5342002-12-27 10:16:42 +000010262#ifdef HAVE_GETLOADAVG
10263PyDoc_STRVAR(posix_getloadavg__doc__,
10264"getloadavg() -> (float, float, float)\n\n\
10265Return the number of processes in the system run queue averaged over\n\
10266the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10267was unobtainable");
10268
10269static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010270posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010271{
10272 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010273 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010274 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10275 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010276 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010277 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010278}
10279#endif
10280
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010281PyDoc_STRVAR(device_encoding__doc__,
10282"device_encoding(fd) -> str\n\n\
10283Return a string describing the encoding of the device\n\
10284if the output is a terminal; else return None.");
10285
10286static PyObject *
10287device_encoding(PyObject *self, PyObject *args)
10288{
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010290
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10292 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010293
10294 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010295}
10296
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010297#ifdef HAVE_SETRESUID
10298PyDoc_STRVAR(posix_setresuid__doc__,
10299"setresuid(ruid, euid, suid)\n\n\
10300Set the current process's real, effective, and saved user ids.");
10301
10302static PyObject*
10303posix_setresuid (PyObject *self, PyObject *args)
10304{
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010306 uid_t ruid, euid, suid;
10307 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10308 _Py_Uid_Converter, &ruid,
10309 _Py_Uid_Converter, &euid,
10310 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 return NULL;
10312 if (setresuid(ruid, euid, suid) < 0)
10313 return posix_error();
10314 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010315}
10316#endif
10317
10318#ifdef HAVE_SETRESGID
10319PyDoc_STRVAR(posix_setresgid__doc__,
10320"setresgid(rgid, egid, sgid)\n\n\
10321Set the current process's real, effective, and saved group ids.");
10322
10323static PyObject*
10324posix_setresgid (PyObject *self, PyObject *args)
10325{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010326 gid_t rgid, egid, sgid;
10327 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10328 _Py_Gid_Converter, &rgid,
10329 _Py_Gid_Converter, &egid,
10330 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 return NULL;
10332 if (setresgid(rgid, egid, sgid) < 0)
10333 return posix_error();
10334 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010335}
10336#endif
10337
10338#ifdef HAVE_GETRESUID
10339PyDoc_STRVAR(posix_getresuid__doc__,
10340"getresuid() -> (ruid, euid, suid)\n\n\
10341Get tuple of the current process's real, effective, and saved user ids.");
10342
10343static PyObject*
10344posix_getresuid (PyObject *self, PyObject *noargs)
10345{
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 if (getresuid(&ruid, &euid, &suid) < 0)
10348 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010349 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10350 _PyLong_FromUid(euid),
10351 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010352}
10353#endif
10354
10355#ifdef HAVE_GETRESGID
10356PyDoc_STRVAR(posix_getresgid__doc__,
10357"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010358Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010359
10360static PyObject*
10361posix_getresgid (PyObject *self, PyObject *noargs)
10362{
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 if (getresgid(&rgid, &egid, &sgid) < 0)
10365 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010366 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10367 _PyLong_FromGid(egid),
10368 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010369}
10370#endif
10371
Benjamin Peterson9428d532011-09-14 11:45:52 -040010372#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010373
Benjamin Peterson799bd802011-08-31 22:15:17 -040010374PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010375"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10376Return the value of extended attribute attribute on path.\n\
10377\n\
10378path may be either a string or an open file descriptor.\n\
10379If follow_symlinks is False, and the last element of the path is a symbolic\n\
10380 link, getxattr will examine the symbolic link itself instead of the file\n\
10381 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010382
10383static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010384posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010385{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010386 path_t path;
10387 path_t attribute;
10388 int follow_symlinks = 1;
10389 PyObject *buffer = NULL;
10390 int i;
10391 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010392
Larry Hastings9cf065c2012-06-22 16:30:09 -070010393 memset(&path, 0, sizeof(path));
10394 memset(&attribute, 0, sizeof(attribute));
10395 path.allow_fd = 1;
10396 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10397 path_converter, &path,
10398 path_converter, &attribute,
10399 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010400 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010401
Larry Hastings9cf065c2012-06-22 16:30:09 -070010402 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10403 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010404
Larry Hastings9cf065c2012-06-22 16:30:09 -070010405 for (i = 0; ; i++) {
10406 void *ptr;
10407 ssize_t result;
10408 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10409 Py_ssize_t buffer_size = buffer_sizes[i];
10410 if (!buffer_size) {
10411 path_error("getxattr", &path);
10412 goto exit;
10413 }
10414 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10415 if (!buffer)
10416 goto exit;
10417 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010418
Larry Hastings9cf065c2012-06-22 16:30:09 -070010419 Py_BEGIN_ALLOW_THREADS;
10420 if (path.fd >= 0)
10421 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10422 else if (follow_symlinks)
10423 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10424 else
10425 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10426 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010427
Larry Hastings9cf065c2012-06-22 16:30:09 -070010428 if (result < 0) {
10429 Py_DECREF(buffer);
10430 buffer = NULL;
10431 if (errno == ERANGE)
10432 continue;
10433 path_error("getxattr", &path);
10434 goto exit;
10435 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010436
Larry Hastings9cf065c2012-06-22 16:30:09 -070010437 if (result != buffer_size) {
10438 /* Can only shrink. */
10439 _PyBytes_Resize(&buffer, result);
10440 }
10441 break;
10442 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010443
Larry Hastings9cf065c2012-06-22 16:30:09 -070010444exit:
10445 path_cleanup(&path);
10446 path_cleanup(&attribute);
10447 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010448}
10449
10450PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010451"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10452Set extended attribute attribute on path to value.\n\
10453path may be either a string or an open file descriptor.\n\
10454If follow_symlinks is False, and the last element of the path is a symbolic\n\
10455 link, setxattr will modify the symbolic link itself instead of the file\n\
10456 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010457
10458static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010459posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010460{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010461 path_t path;
10462 path_t attribute;
10463 Py_buffer value;
10464 int flags = 0;
10465 int follow_symlinks = 1;
10466 int result;
10467 PyObject *return_value = NULL;
10468 static char *keywords[] = {"path", "attribute", "value",
10469 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010470
Larry Hastings9cf065c2012-06-22 16:30:09 -070010471 memset(&path, 0, sizeof(path));
10472 path.allow_fd = 1;
10473 memset(&attribute, 0, sizeof(attribute));
10474 memset(&value, 0, sizeof(value));
10475 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10476 keywords,
10477 path_converter, &path,
10478 path_converter, &attribute,
10479 &value, &flags,
10480 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010481 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010482
10483 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10484 goto exit;
10485
Benjamin Peterson799bd802011-08-31 22:15:17 -040010486 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010487 if (path.fd > -1)
10488 result = fsetxattr(path.fd, attribute.narrow,
10489 value.buf, value.len, flags);
10490 else if (follow_symlinks)
10491 result = setxattr(path.narrow, attribute.narrow,
10492 value.buf, value.len, flags);
10493 else
10494 result = lsetxattr(path.narrow, attribute.narrow,
10495 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010496 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010497
Larry Hastings9cf065c2012-06-22 16:30:09 -070010498 if (result) {
10499 return_value = path_error("setxattr", &path);
10500 goto exit;
10501 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010502
Larry Hastings9cf065c2012-06-22 16:30:09 -070010503 return_value = Py_None;
10504 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010505
Larry Hastings9cf065c2012-06-22 16:30:09 -070010506exit:
10507 path_cleanup(&path);
10508 path_cleanup(&attribute);
10509 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010510
Larry Hastings9cf065c2012-06-22 16:30:09 -070010511 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010512}
10513
10514PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010515"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10516Remove extended attribute attribute on path.\n\
10517path may be either a string or an open file descriptor.\n\
10518If follow_symlinks is False, and the last element of the path is a symbolic\n\
10519 link, removexattr will modify the symbolic link itself instead of the file\n\
10520 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010521
10522static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010523posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010524{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010525 path_t path;
10526 path_t attribute;
10527 int follow_symlinks = 1;
10528 int result;
10529 PyObject *return_value = NULL;
10530 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010531
Larry Hastings9cf065c2012-06-22 16:30:09 -070010532 memset(&path, 0, sizeof(path));
10533 memset(&attribute, 0, sizeof(attribute));
10534 path.allow_fd = 1;
10535 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10536 keywords,
10537 path_converter, &path,
10538 path_converter, &attribute,
10539 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010540 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010541
10542 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10543 goto exit;
10544
Benjamin Peterson799bd802011-08-31 22:15:17 -040010545 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010546 if (path.fd > -1)
10547 result = fremovexattr(path.fd, attribute.narrow);
10548 else if (follow_symlinks)
10549 result = removexattr(path.narrow, attribute.narrow);
10550 else
10551 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010552 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010553
Larry Hastings9cf065c2012-06-22 16:30:09 -070010554 if (result) {
10555 return_value = path_error("removexattr", &path);
10556 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010557 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010558
Larry Hastings9cf065c2012-06-22 16:30:09 -070010559 return_value = Py_None;
10560 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561
Larry Hastings9cf065c2012-06-22 16:30:09 -070010562exit:
10563 path_cleanup(&path);
10564 path_cleanup(&attribute);
10565
10566 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010567}
10568
10569PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010570"listxattr(path='.', *, follow_symlinks=True)\n\n\
10571Return a list of extended attributes on path.\n\
10572\n\
10573path may be either None, a string, or an open file descriptor.\n\
10574if path is None, listxattr will examine the current directory.\n\
10575If follow_symlinks is False, and the last element of the path is a symbolic\n\
10576 link, listxattr will examine the symbolic link itself instead of the file\n\
10577 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010578
10579static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010580posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010581{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010582 path_t path;
10583 int follow_symlinks = 1;
10584 Py_ssize_t i;
10585 PyObject *result = NULL;
10586 char *buffer = NULL;
10587 char *name;
10588 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010589
Larry Hastings9cf065c2012-06-22 16:30:09 -070010590 memset(&path, 0, sizeof(path));
10591 path.allow_fd = 1;
10592 path.fd = -1;
10593 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10594 path_converter, &path,
10595 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010596 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010597
Larry Hastings9cf065c2012-06-22 16:30:09 -070010598 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10599 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010600
Larry Hastings9cf065c2012-06-22 16:30:09 -070010601 name = path.narrow ? path.narrow : ".";
10602 for (i = 0; ; i++) {
10603 char *start, *trace, *end;
10604 ssize_t length;
10605 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10606 Py_ssize_t buffer_size = buffer_sizes[i];
10607 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010608 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010609 path_error("listxattr", &path);
10610 break;
10611 }
10612 buffer = PyMem_MALLOC(buffer_size);
10613 if (!buffer) {
10614 PyErr_NoMemory();
10615 break;
10616 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010617
Larry Hastings9cf065c2012-06-22 16:30:09 -070010618 Py_BEGIN_ALLOW_THREADS;
10619 if (path.fd > -1)
10620 length = flistxattr(path.fd, buffer, buffer_size);
10621 else if (follow_symlinks)
10622 length = listxattr(name, buffer, buffer_size);
10623 else
10624 length = llistxattr(name, buffer, buffer_size);
10625 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010626
Larry Hastings9cf065c2012-06-22 16:30:09 -070010627 if (length < 0) {
10628 if (errno == ERANGE)
10629 continue;
10630 path_error("listxattr", &path);
10631 break;
10632 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010633
Larry Hastings9cf065c2012-06-22 16:30:09 -070010634 result = PyList_New(0);
10635 if (!result) {
10636 goto exit;
10637 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010638
Larry Hastings9cf065c2012-06-22 16:30:09 -070010639 end = buffer + length;
10640 for (trace = start = buffer; trace != end; trace++) {
10641 if (!*trace) {
10642 int error;
10643 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10644 trace - start);
10645 if (!attribute) {
10646 Py_DECREF(result);
10647 result = NULL;
10648 goto exit;
10649 }
10650 error = PyList_Append(result, attribute);
10651 Py_DECREF(attribute);
10652 if (error) {
10653 Py_DECREF(result);
10654 result = NULL;
10655 goto exit;
10656 }
10657 start = trace + 1;
10658 }
10659 }
10660 break;
10661 }
10662exit:
10663 path_cleanup(&path);
10664 if (buffer)
10665 PyMem_FREE(buffer);
10666 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010667}
10668
Benjamin Peterson9428d532011-09-14 11:45:52 -040010669#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010671
Georg Brandl2fb477c2012-02-21 00:33:36 +010010672PyDoc_STRVAR(posix_urandom__doc__,
10673"urandom(n) -> str\n\n\
10674Return n random bytes suitable for cryptographic use.");
10675
10676static PyObject *
10677posix_urandom(PyObject *self, PyObject *args)
10678{
10679 Py_ssize_t size;
10680 PyObject *result;
10681 int ret;
10682
10683 /* Read arguments */
10684 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10685 return NULL;
10686 if (size < 0)
10687 return PyErr_Format(PyExc_ValueError,
10688 "negative argument not allowed");
10689 result = PyBytes_FromStringAndSize(NULL, size);
10690 if (result == NULL)
10691 return NULL;
10692
10693 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10694 PyBytes_GET_SIZE(result));
10695 if (ret == -1) {
10696 Py_DECREF(result);
10697 return NULL;
10698 }
10699 return result;
10700}
10701
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010702/* Terminal size querying */
10703
10704static PyTypeObject TerminalSizeType;
10705
10706PyDoc_STRVAR(TerminalSize_docstring,
10707 "A tuple of (columns, lines) for holding terminal window size");
10708
10709static PyStructSequence_Field TerminalSize_fields[] = {
10710 {"columns", "width of the terminal window in characters"},
10711 {"lines", "height of the terminal window in characters"},
10712 {NULL, NULL}
10713};
10714
10715static PyStructSequence_Desc TerminalSize_desc = {
10716 "os.terminal_size",
10717 TerminalSize_docstring,
10718 TerminalSize_fields,
10719 2,
10720};
10721
10722#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10723PyDoc_STRVAR(termsize__doc__,
10724 "Return the size of the terminal window as (columns, lines).\n" \
10725 "\n" \
10726 "The optional argument fd (default standard output) specifies\n" \
10727 "which file descriptor should be queried.\n" \
10728 "\n" \
10729 "If the file descriptor is not connected to a terminal, an OSError\n" \
10730 "is thrown.\n" \
10731 "\n" \
10732 "This function will only be defined if an implementation is\n" \
10733 "available for this system.\n" \
10734 "\n" \
10735 "shutil.get_terminal_size is the high-level function which should \n" \
10736 "normally be used, os.get_terminal_size is the low-level implementation.");
10737
10738static PyObject*
10739get_terminal_size(PyObject *self, PyObject *args)
10740{
10741 int columns, lines;
10742 PyObject *termsize;
10743
10744 int fd = fileno(stdout);
10745 /* Under some conditions stdout may not be connected and
10746 * fileno(stdout) may point to an invalid file descriptor. For example
10747 * GUI apps don't have valid standard streams by default.
10748 *
10749 * If this happens, and the optional fd argument is not present,
10750 * the ioctl below will fail returning EBADF. This is what we want.
10751 */
10752
10753 if (!PyArg_ParseTuple(args, "|i", &fd))
10754 return NULL;
10755
10756#ifdef TERMSIZE_USE_IOCTL
10757 {
10758 struct winsize w;
10759 if (ioctl(fd, TIOCGWINSZ, &w))
10760 return PyErr_SetFromErrno(PyExc_OSError);
10761 columns = w.ws_col;
10762 lines = w.ws_row;
10763 }
10764#endif /* TERMSIZE_USE_IOCTL */
10765
10766#ifdef TERMSIZE_USE_CONIO
10767 {
10768 DWORD nhandle;
10769 HANDLE handle;
10770 CONSOLE_SCREEN_BUFFER_INFO csbi;
10771 switch (fd) {
10772 case 0: nhandle = STD_INPUT_HANDLE;
10773 break;
10774 case 1: nhandle = STD_OUTPUT_HANDLE;
10775 break;
10776 case 2: nhandle = STD_ERROR_HANDLE;
10777 break;
10778 default:
10779 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10780 }
10781 handle = GetStdHandle(nhandle);
10782 if (handle == NULL)
10783 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10784 if (handle == INVALID_HANDLE_VALUE)
10785 return PyErr_SetFromWindowsErr(0);
10786
10787 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10788 return PyErr_SetFromWindowsErr(0);
10789
10790 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10791 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10792 }
10793#endif /* TERMSIZE_USE_CONIO */
10794
10795 termsize = PyStructSequence_New(&TerminalSizeType);
10796 if (termsize == NULL)
10797 return NULL;
10798 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10799 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10800 if (PyErr_Occurred()) {
10801 Py_DECREF(termsize);
10802 return NULL;
10803 }
10804 return termsize;
10805}
10806#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10807
10808
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010809static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010810 {"access", (PyCFunction)posix_access,
10811 METH_VARARGS | METH_KEYWORDS,
10812 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010813#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010814 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010815#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010816 {"chdir", (PyCFunction)posix_chdir,
10817 METH_VARARGS | METH_KEYWORDS,
10818 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010819#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010820 {"chflags", (PyCFunction)posix_chflags,
10821 METH_VARARGS | METH_KEYWORDS,
10822 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010823#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010824 {"chmod", (PyCFunction)posix_chmod,
10825 METH_VARARGS | METH_KEYWORDS,
10826 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010827#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010828 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010829#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010830#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010831 {"chown", (PyCFunction)posix_chown,
10832 METH_VARARGS | METH_KEYWORDS,
10833 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010834#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010835#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010837#endif /* HAVE_LCHMOD */
10838#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010840#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010841#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010843#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010844#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010845 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010846#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010847#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010848 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010849#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010850#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010851 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010852#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010853#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10855 METH_NOARGS, posix_getcwd__doc__},
10856 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10857 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010858#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010859#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10860 {"link", (PyCFunction)posix_link,
10861 METH_VARARGS | METH_KEYWORDS,
10862 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010863#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010864 {"listdir", (PyCFunction)posix_listdir,
10865 METH_VARARGS | METH_KEYWORDS,
10866 posix_listdir__doc__},
10867 {"lstat", (PyCFunction)posix_lstat,
10868 METH_VARARGS | METH_KEYWORDS,
10869 posix_lstat__doc__},
10870 {"mkdir", (PyCFunction)posix_mkdir,
10871 METH_VARARGS | METH_KEYWORDS,
10872 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010873#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010875#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010876#ifdef HAVE_GETPRIORITY
10877 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10878#endif /* HAVE_GETPRIORITY */
10879#ifdef HAVE_SETPRIORITY
10880 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10881#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010882#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010883 {"readlink", (PyCFunction)posix_readlink,
10884 METH_VARARGS | METH_KEYWORDS,
10885 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010886#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010887#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010888 {"readlink", (PyCFunction)win_readlink,
10889 METH_VARARGS | METH_KEYWORDS,
10890 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010891#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010892 {"rename", (PyCFunction)posix_rename,
10893 METH_VARARGS | METH_KEYWORDS,
10894 posix_rename__doc__},
10895 {"replace", (PyCFunction)posix_replace,
10896 METH_VARARGS | METH_KEYWORDS,
10897 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010898 {"rmdir", (PyCFunction)posix_rmdir,
10899 METH_VARARGS | METH_KEYWORDS,
10900 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010901 {"stat", (PyCFunction)posix_stat,
10902 METH_VARARGS | METH_KEYWORDS,
10903 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010905#if defined(HAVE_SYMLINK)
10906 {"symlink", (PyCFunction)posix_symlink,
10907 METH_VARARGS | METH_KEYWORDS,
10908 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010909#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010910#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010912#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010914#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010915 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010916#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010917 {"unlink", (PyCFunction)posix_unlink,
10918 METH_VARARGS | METH_KEYWORDS,
10919 posix_unlink__doc__},
10920 {"remove", (PyCFunction)posix_unlink,
10921 METH_VARARGS | METH_KEYWORDS,
10922 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010923 {"utime", (PyCFunction)posix_utime,
10924 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010925#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010926 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010927#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010928 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010929#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010931 {"execve", (PyCFunction)posix_execve,
10932 METH_VARARGS | METH_KEYWORDS,
10933 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010934#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010935#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10937 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010938#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10940 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010941#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010942#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010943#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010944 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010945#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010946#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010947 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010948#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010949#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010950#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010951 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10952 {"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 +020010953#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010954#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010955 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010956#endif
10957#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010958 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010959#endif
10960#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010961 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010962#endif
10963#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010964 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010965#endif
10966#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010967 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010968#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010969 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010970#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010971 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10972 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10973#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010974#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010975#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010977#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010978#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010980#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010981#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010983#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010984#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010985 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010986#endif /* HAVE_GETEUID */
10987#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010989#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010990#ifdef HAVE_GETGROUPLIST
10991 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10992#endif
Fred Drakec9680921999-12-13 16:37:25 +000010993#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010995#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010996 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010997#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010999#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011000#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011002#endif /* HAVE_GETPPID */
11003#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011005#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011006#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011008#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011009#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011011#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011012#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011014#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011015#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011016 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011017#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011018#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011019 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11020 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011021#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011022#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011024#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011025#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011027#endif /* HAVE_SETEUID */
11028#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011030#endif /* HAVE_SETEGID */
11031#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011033#endif /* HAVE_SETREUID */
11034#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011036#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011037#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011039#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011040#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011042#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011043#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011045#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011046#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011048#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011049#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011051#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011052#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011053 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011054#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011055#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011056 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011057#endif /* HAVE_WAIT3 */
11058#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011059 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011060#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011061#if defined(HAVE_WAITID) && !defined(__APPLE__)
11062 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11063#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011064#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011066#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011067#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011069#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011070#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011072#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011073#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011075#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011076#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011077 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011078#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011079#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011081#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011082 {"open", (PyCFunction)posix_open,\
11083 METH_VARARGS | METH_KEYWORDS,
11084 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011085 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11086 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11087 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11088 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11089 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011090#ifdef HAVE_LOCKF
11091 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11092#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11094 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011095#ifdef HAVE_READV
11096 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11097#endif
11098#ifdef HAVE_PREAD
11099 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11100#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011101 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011102#ifdef HAVE_WRITEV
11103 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11104#endif
11105#ifdef HAVE_PWRITE
11106 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11107#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011108#ifdef HAVE_SENDFILE
11109 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11110 posix_sendfile__doc__},
11111#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011112 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011114#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011116#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011117#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011118 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011119#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011120#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011121 {"mkfifo", (PyCFunction)posix_mkfifo,
11122 METH_VARARGS | METH_KEYWORDS,
11123 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011124#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011125#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011126 {"mknod", (PyCFunction)posix_mknod,
11127 METH_VARARGS | METH_KEYWORDS,
11128 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011129#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011130#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11132 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11133 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011134#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011135#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011137#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011138#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011139 {"truncate", (PyCFunction)posix_truncate,
11140 METH_VARARGS | METH_KEYWORDS,
11141 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011142#endif
11143#ifdef HAVE_POSIX_FALLOCATE
11144 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11145#endif
11146#ifdef HAVE_POSIX_FADVISE
11147 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11148#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011149#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011150 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011151#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011152#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011153 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011154#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011156#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011158#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011159#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011161#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011162#ifdef HAVE_SYNC
11163 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11164#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011165#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011167#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011168#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011169#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011171#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011172#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011174#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011175#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011177#endif /* WIFSTOPPED */
11178#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011180#endif /* WIFSIGNALED */
11181#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011183#endif /* WIFEXITED */
11184#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011186#endif /* WEXITSTATUS */
11187#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011188 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011189#endif /* WTERMSIG */
11190#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011191 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011192#endif /* WSTOPSIG */
11193#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011194#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011195 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011196#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011197#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011198 {"statvfs", (PyCFunction)posix_statvfs,
11199 METH_VARARGS | METH_KEYWORDS,
11200 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011201#endif
Fred Drakec9680921999-12-13 16:37:25 +000011202#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011204#endif
11205#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011206 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011207#endif
11208#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011210#endif
11211#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011212 {"pathconf", (PyCFunction)posix_pathconf,
11213 METH_VARARGS | METH_KEYWORDS,
11214 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011215#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011216 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011217#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011218 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011219 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011220 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011221 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011222 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011223#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011224#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011225 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011226#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011227 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011228#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011230#endif
11231#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011233#endif
11234#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011235 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011236#endif
11237#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011239#endif
11240
Benjamin Peterson9428d532011-09-14 11:45:52 -040011241#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011242 {"setxattr", (PyCFunction)posix_setxattr,
11243 METH_VARARGS | METH_KEYWORDS,
11244 posix_setxattr__doc__},
11245 {"getxattr", (PyCFunction)posix_getxattr,
11246 METH_VARARGS | METH_KEYWORDS,
11247 posix_getxattr__doc__},
11248 {"removexattr", (PyCFunction)posix_removexattr,
11249 METH_VARARGS | METH_KEYWORDS,
11250 posix_removexattr__doc__},
11251 {"listxattr", (PyCFunction)posix_listxattr,
11252 METH_VARARGS | METH_KEYWORDS,
11253 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011254#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011255#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11256 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11257#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011258 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011259};
11260
11261
Barry Warsaw4a342091996-12-19 23:50:02 +000011262static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011263ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011264{
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011266}
11267
Guido van Rossumd48f2521997-12-05 22:19:34 +000011268#if defined(PYOS_OS2)
11269/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011270static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011271{
11272 APIRET rc;
11273 ULONG values[QSV_MAX+1];
11274 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011275 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011276
11277 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011278 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011279 Py_END_ALLOW_THREADS
11280
11281 if (rc != NO_ERROR) {
11282 os2_error(rc);
11283 return -1;
11284 }
11285
Fred Drake4d1e64b2002-04-15 19:40:07 +000011286 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11287 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11288 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11289 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11290 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11291 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11292 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011293
11294 switch (values[QSV_VERSION_MINOR]) {
11295 case 0: ver = "2.00"; break;
11296 case 10: ver = "2.10"; break;
11297 case 11: ver = "2.11"; break;
11298 case 30: ver = "3.00"; break;
11299 case 40: ver = "4.00"; break;
11300 case 50: ver = "5.00"; break;
11301 default:
Tim Peters885d4572001-11-28 20:27:42 +000011302 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011304 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011305 ver = &tmp[0];
11306 }
11307
11308 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011309 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011310 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011311
11312 /* Add Indicator of Which Drive was Used to Boot the System */
11313 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11314 tmp[1] = ':';
11315 tmp[2] = '\0';
11316
Fred Drake4d1e64b2002-04-15 19:40:07 +000011317 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011318}
11319#endif
11320
Brian Curtin52173d42010-12-02 18:29:18 +000011321#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011322static int
Brian Curtin52173d42010-12-02 18:29:18 +000011323enable_symlink()
11324{
11325 HANDLE tok;
11326 TOKEN_PRIVILEGES tok_priv;
11327 LUID luid;
11328 int meth_idx = 0;
11329
11330 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011331 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011332
11333 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011334 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011335
11336 tok_priv.PrivilegeCount = 1;
11337 tok_priv.Privileges[0].Luid = luid;
11338 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11339
11340 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11341 sizeof(TOKEN_PRIVILEGES),
11342 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011343 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011344
Brian Curtin3b4499c2010-12-28 14:31:47 +000011345 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11346 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011347}
11348#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11349
Barry Warsaw4a342091996-12-19 23:50:02 +000011350static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011351all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011352{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011353#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011355#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011356#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011358#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011359#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011361#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011362#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011364#endif
Fred Drakec9680921999-12-13 16:37:25 +000011365#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011367#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011368#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011370#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011371#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011373#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011374#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011376#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011377#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011379#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011380#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011382#endif
11383#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011385#endif
11386#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011388#endif
11389#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011391#endif
11392#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011394#endif
11395#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011397#endif
11398#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011400#endif
11401#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011403#endif
11404#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011406#endif
11407#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011409#endif
11410#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011412#endif
11413#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011415#endif
11416#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011418#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011419#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011420 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011421#endif
11422#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011424#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011425#ifdef O_XATTR
11426 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11427#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011428#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011430#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011431#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011432 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011433#endif
11434#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011435 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011436#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011437#ifdef O_EXEC
11438 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11439#endif
11440#ifdef O_SEARCH
11441 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11442#endif
11443#ifdef O_TTY_INIT
11444 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11445#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011446#ifdef PRIO_PROCESS
11447 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11448#endif
11449#ifdef PRIO_PGRP
11450 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11451#endif
11452#ifdef PRIO_USER
11453 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11454#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011455#ifdef O_CLOEXEC
11456 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11457#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011458#ifdef O_ACCMODE
11459 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11460#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011461
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011462
Jesus Cea94363612012-06-22 18:32:07 +020011463#ifdef SEEK_HOLE
11464 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11465#endif
11466#ifdef SEEK_DATA
11467 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11468#endif
11469
Tim Peters5aa91602002-01-30 05:46:57 +000011470/* MS Windows */
11471#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011472 /* Don't inherit in child processes. */
11473 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011474#endif
11475#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011476 /* Optimize for short life (keep in memory). */
11477 /* MS forgot to define this one with a non-underscore form too. */
11478 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011479#endif
11480#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011481 /* Automatically delete when last handle is closed. */
11482 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011483#endif
11484#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011485 /* Optimize for random access. */
11486 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011487#endif
11488#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 /* Optimize for sequential access. */
11490 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011491#endif
11492
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011493/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011494#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011495 /* Send a SIGIO signal whenever input or output
11496 becomes available on file descriptor */
11497 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011498#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011499#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011500 /* Direct disk access. */
11501 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011502#endif
11503#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011504 /* Must be a directory. */
11505 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011506#endif
11507#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 /* Do not follow links. */
11509 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011510#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011511#ifdef O_NOLINKS
11512 /* Fails if link count of the named file is greater than 1 */
11513 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11514#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011515#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 /* Do not update the access time. */
11517 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011518#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011519
Victor Stinner8c62be82010-05-06 00:08:46 +000011520 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011521#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011523#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011524#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011526#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011527#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011529#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011530#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011532#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011533#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011535#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011536#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011538#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011539#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011541#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011542#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011544#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011545#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011547#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011548#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011550#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011551#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011553#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011554#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011556#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011557#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011559#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011560#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011562#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011563#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011565#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011566#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011567 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011568#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011569#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011571#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011572
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011573 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011574#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011575 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011576#endif /* ST_RDONLY */
11577#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011578 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011579#endif /* ST_NOSUID */
11580
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011581 /* FreeBSD sendfile() constants */
11582#ifdef SF_NODISKIO
11583 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11584#endif
11585#ifdef SF_MNOWAIT
11586 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11587#endif
11588#ifdef SF_SYNC
11589 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11590#endif
11591
Ross Lagerwall7807c352011-03-17 20:20:30 +020011592 /* constants for posix_fadvise */
11593#ifdef POSIX_FADV_NORMAL
11594 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11595#endif
11596#ifdef POSIX_FADV_SEQUENTIAL
11597 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11598#endif
11599#ifdef POSIX_FADV_RANDOM
11600 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11601#endif
11602#ifdef POSIX_FADV_NOREUSE
11603 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11604#endif
11605#ifdef POSIX_FADV_WILLNEED
11606 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11607#endif
11608#ifdef POSIX_FADV_DONTNEED
11609 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11610#endif
11611
11612 /* constants for waitid */
11613#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11614 if (ins(d, "P_PID", (long)P_PID)) return -1;
11615 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11616 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11617#endif
11618#ifdef WEXITED
11619 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11620#endif
11621#ifdef WNOWAIT
11622 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11623#endif
11624#ifdef WSTOPPED
11625 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11626#endif
11627#ifdef CLD_EXITED
11628 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11629#endif
11630#ifdef CLD_DUMPED
11631 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11632#endif
11633#ifdef CLD_TRAPPED
11634 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11635#endif
11636#ifdef CLD_CONTINUED
11637 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11638#endif
11639
11640 /* constants for lockf */
11641#ifdef F_LOCK
11642 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11643#endif
11644#ifdef F_TLOCK
11645 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11646#endif
11647#ifdef F_ULOCK
11648 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11649#endif
11650#ifdef F_TEST
11651 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11652#endif
11653
Guido van Rossum246bc171999-02-01 23:54:31 +000011654#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011655#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011656 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11657 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11658 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11659 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11660 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11661 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11662 if (ins(d, "P_PM", (long)P_PM)) return -1;
11663 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11664 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11665 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11666 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11667 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11668 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11669 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11670 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11671 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11672 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11673 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11674 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11675 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011676#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011677 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11678 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11679 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11680 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11681 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011682#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011683#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011684
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011685#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011686 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011687 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11688 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11689#ifdef SCHED_SPORADIC
11690 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11691#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011692#ifdef SCHED_BATCH
11693 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11694#endif
11695#ifdef SCHED_IDLE
11696 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11697#endif
11698#ifdef SCHED_RESET_ON_FORK
11699 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11700#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011701#ifdef SCHED_SYS
11702 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11703#endif
11704#ifdef SCHED_IA
11705 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11706#endif
11707#ifdef SCHED_FSS
11708 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11709#endif
11710#ifdef SCHED_FX
11711 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11712#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011713#endif
11714
Benjamin Peterson9428d532011-09-14 11:45:52 -040011715#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011716 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11717 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11718 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11719#endif
11720
Victor Stinner8b905bd2011-10-25 13:34:04 +020011721#ifdef RTLD_LAZY
11722 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11723#endif
11724#ifdef RTLD_NOW
11725 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11726#endif
11727#ifdef RTLD_GLOBAL
11728 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11729#endif
11730#ifdef RTLD_LOCAL
11731 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11732#endif
11733#ifdef RTLD_NODELETE
11734 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11735#endif
11736#ifdef RTLD_NOLOAD
11737 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11738#endif
11739#ifdef RTLD_DEEPBIND
11740 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11741#endif
11742
Guido van Rossumd48f2521997-12-05 22:19:34 +000011743#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011744 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011745#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011747}
11748
11749
Tim Peters5aa91602002-01-30 05:46:57 +000011750#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011751#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011752#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011753
11754#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011755#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011756#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011757
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011758#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011759#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011760#define MODNAME "posix"
11761#endif
11762
Martin v. Löwis1a214512008-06-11 05:26:20 +000011763static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011764 PyModuleDef_HEAD_INIT,
11765 MODNAME,
11766 posix__doc__,
11767 -1,
11768 posix_methods,
11769 NULL,
11770 NULL,
11771 NULL,
11772 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011773};
11774
11775
Larry Hastings9cf065c2012-06-22 16:30:09 -070011776static char *have_functions[] = {
11777
11778#ifdef HAVE_FACCESSAT
11779 "HAVE_FACCESSAT",
11780#endif
11781
11782#ifdef HAVE_FCHDIR
11783 "HAVE_FCHDIR",
11784#endif
11785
11786#ifdef HAVE_FCHMOD
11787 "HAVE_FCHMOD",
11788#endif
11789
11790#ifdef HAVE_FCHMODAT
11791 "HAVE_FCHMODAT",
11792#endif
11793
11794#ifdef HAVE_FCHOWN
11795 "HAVE_FCHOWN",
11796#endif
11797
11798#ifdef HAVE_FEXECVE
11799 "HAVE_FEXECVE",
11800#endif
11801
11802#ifdef HAVE_FDOPENDIR
11803 "HAVE_FDOPENDIR",
11804#endif
11805
Georg Brandl306336b2012-06-24 12:55:33 +020011806#ifdef HAVE_FPATHCONF
11807 "HAVE_FPATHCONF",
11808#endif
11809
Larry Hastings9cf065c2012-06-22 16:30:09 -070011810#ifdef HAVE_FSTATAT
11811 "HAVE_FSTATAT",
11812#endif
11813
11814#ifdef HAVE_FSTATVFS
11815 "HAVE_FSTATVFS",
11816#endif
11817
Georg Brandl306336b2012-06-24 12:55:33 +020011818#ifdef HAVE_FTRUNCATE
11819 "HAVE_FTRUNCATE",
11820#endif
11821
Larry Hastings9cf065c2012-06-22 16:30:09 -070011822#ifdef HAVE_FUTIMENS
11823 "HAVE_FUTIMENS",
11824#endif
11825
11826#ifdef HAVE_FUTIMES
11827 "HAVE_FUTIMES",
11828#endif
11829
11830#ifdef HAVE_FUTIMESAT
11831 "HAVE_FUTIMESAT",
11832#endif
11833
11834#ifdef HAVE_LINKAT
11835 "HAVE_LINKAT",
11836#endif
11837
11838#ifdef HAVE_LCHFLAGS
11839 "HAVE_LCHFLAGS",
11840#endif
11841
11842#ifdef HAVE_LCHMOD
11843 "HAVE_LCHMOD",
11844#endif
11845
11846#ifdef HAVE_LCHOWN
11847 "HAVE_LCHOWN",
11848#endif
11849
11850#ifdef HAVE_LSTAT
11851 "HAVE_LSTAT",
11852#endif
11853
11854#ifdef HAVE_LUTIMES
11855 "HAVE_LUTIMES",
11856#endif
11857
11858#ifdef HAVE_MKDIRAT
11859 "HAVE_MKDIRAT",
11860#endif
11861
11862#ifdef HAVE_MKFIFOAT
11863 "HAVE_MKFIFOAT",
11864#endif
11865
11866#ifdef HAVE_MKNODAT
11867 "HAVE_MKNODAT",
11868#endif
11869
11870#ifdef HAVE_OPENAT
11871 "HAVE_OPENAT",
11872#endif
11873
11874#ifdef HAVE_READLINKAT
11875 "HAVE_READLINKAT",
11876#endif
11877
11878#ifdef HAVE_RENAMEAT
11879 "HAVE_RENAMEAT",
11880#endif
11881
11882#ifdef HAVE_SYMLINKAT
11883 "HAVE_SYMLINKAT",
11884#endif
11885
11886#ifdef HAVE_UNLINKAT
11887 "HAVE_UNLINKAT",
11888#endif
11889
11890#ifdef HAVE_UTIMENSAT
11891 "HAVE_UTIMENSAT",
11892#endif
11893
11894#ifdef MS_WINDOWS
11895 "MS_WINDOWS",
11896#endif
11897
11898 NULL
11899};
11900
11901
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011902PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011903INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011904{
Victor Stinner8c62be82010-05-06 00:08:46 +000011905 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011906 PyObject *list;
11907 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011908
Brian Curtin52173d42010-12-02 18:29:18 +000011909#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011910 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011911#endif
11912
Victor Stinner8c62be82010-05-06 00:08:46 +000011913 m = PyModule_Create(&posixmodule);
11914 if (m == NULL)
11915 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011916
Victor Stinner8c62be82010-05-06 00:08:46 +000011917 /* Initialize environ dictionary */
11918 v = convertenviron();
11919 Py_XINCREF(v);
11920 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11921 return NULL;
11922 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011923
Victor Stinner8c62be82010-05-06 00:08:46 +000011924 if (all_ins(m))
11925 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011926
Victor Stinner8c62be82010-05-06 00:08:46 +000011927 if (setup_confname_tables(m))
11928 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011929
Victor Stinner8c62be82010-05-06 00:08:46 +000011930 Py_INCREF(PyExc_OSError);
11931 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011932
Guido van Rossumb3d39562000-01-31 18:41:26 +000011933#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011934 if (posix_putenv_garbage == NULL)
11935 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011936#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011937
Victor Stinner8c62be82010-05-06 00:08:46 +000011938 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011939#if defined(HAVE_WAITID) && !defined(__APPLE__)
11940 waitid_result_desc.name = MODNAME ".waitid_result";
11941 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11942#endif
11943
Victor Stinner8c62be82010-05-06 00:08:46 +000011944 stat_result_desc.name = MODNAME ".stat_result";
11945 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11946 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11947 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11948 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11949 structseq_new = StatResultType.tp_new;
11950 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011951
Victor Stinner8c62be82010-05-06 00:08:46 +000011952 statvfs_result_desc.name = MODNAME ".statvfs_result";
11953 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011954#ifdef NEED_TICKS_PER_SECOND
11955# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011956 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011957# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011958 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011959# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011960 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011961# endif
11962#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011963
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011964#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011965 sched_param_desc.name = MODNAME ".sched_param";
11966 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11967 SchedParamType.tp_new = sched_param_new;
11968#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011969
11970 /* initialize TerminalSize_info */
11971 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011972 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011973#if defined(HAVE_WAITID) && !defined(__APPLE__)
11974 Py_INCREF((PyObject*) &WaitidResultType);
11975 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11976#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011977 Py_INCREF((PyObject*) &StatResultType);
11978 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11979 Py_INCREF((PyObject*) &StatVFSResultType);
11980 PyModule_AddObject(m, "statvfs_result",
11981 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011982
11983#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011984 Py_INCREF(&SchedParamType);
11985 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011986#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011987
Larry Hastings605a62d2012-06-24 04:33:36 -070011988 times_result_desc.name = MODNAME ".times_result";
11989 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11990 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11991
11992 uname_result_desc.name = MODNAME ".uname_result";
11993 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11994 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11995
Thomas Wouters477c8d52006-05-27 19:21:47 +000011996#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011997 /*
11998 * Step 2 of weak-linking support on Mac OS X.
11999 *
12000 * The code below removes functions that are not available on the
12001 * currently active platform.
12002 *
12003 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012004 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012005 * OSX 10.4.
12006 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012007#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012008 if (fstatvfs == NULL) {
12009 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12010 return NULL;
12011 }
12012 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012013#endif /* HAVE_FSTATVFS */
12014
12015#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012016 if (statvfs == NULL) {
12017 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12018 return NULL;
12019 }
12020 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012021#endif /* HAVE_STATVFS */
12022
12023# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012024 if (lchown == NULL) {
12025 if (PyObject_DelAttrString(m, "lchown") == -1) {
12026 return NULL;
12027 }
12028 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012029#endif /* HAVE_LCHOWN */
12030
12031
12032#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012033
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012034 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012035 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12036
Larry Hastings6fe20b32012-04-19 15:07:49 -070012037 billion = PyLong_FromLong(1000000000);
12038 if (!billion)
12039 return NULL;
12040
Larry Hastings9cf065c2012-06-22 16:30:09 -070012041 /* suppress "function not used" warnings */
12042 {
12043 int ignored;
12044 fd_specified("", -1);
12045 follow_symlinks_specified("", 1);
12046 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12047 dir_fd_converter(Py_None, &ignored);
12048 dir_fd_unavailable(Py_None, &ignored);
12049 }
12050
12051 /*
12052 * provide list of locally available functions
12053 * so os.py can populate support_* lists
12054 */
12055 list = PyList_New(0);
12056 if (!list)
12057 return NULL;
12058 for (trace = have_functions; *trace; trace++) {
12059 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12060 if (!unicode)
12061 return NULL;
12062 if (PyList_Append(list, unicode))
12063 return NULL;
12064 Py_DECREF(unicode);
12065 }
12066 PyModule_AddObject(m, "_have_functions", list);
12067
12068 initialized = 1;
12069
Victor Stinner8c62be82010-05-06 00:08:46 +000012070 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012071
Guido van Rossumb6775db1994-08-01 11:34:53 +000012072}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012073
12074#ifdef __cplusplus
12075}
12076#endif