blob: 3b4b5704ec8424d1d957441535ed05bb355e7463 [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 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004517 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004518 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
Jason R. Coombs3a092862013-05-27 23:21:28 -04007203void _dirnameW(WCHAR *path) {
7204 /* Remove the last portion of the path */
7205
7206 WCHAR *ptr;
7207
7208 /* walk the path from the end until a backslash is encountered */
7209 for(ptr = path + wcslen(path); ptr != path; ptr--)
7210 {
7211 if(*ptr == *L"\\" || *ptr == *L"/") {
7212 break;
7213 }
7214 }
7215 *ptr = 0;
7216}
7217
7218void _dirnameA(char *path) {
7219 /* Remove the last portion of the path */
7220
7221 char *ptr;
7222
7223 /* walk the path from the end until a backslash is encountered */
7224 for(ptr = path + strlen(path); ptr != path; ptr--)
7225 {
7226 if(*ptr == '\\' || *ptr == '/') {
7227 break;
7228 }
7229 }
7230 *ptr = 0;
7231}
7232
7233int _is_absW(WCHAR *path) {
7234 /* Is this path absolute? */
7235
7236 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7237
7238}
7239
7240int _is_absA(char *path) {
7241 /* Is this path absolute? */
7242
7243 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7244
7245}
7246
7247void _joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) {
7248 /* join root and rest with a backslash */
7249 int root_len;
7250
7251 if(_is_absW(rest)) {
7252 wcscpy(dest_path, rest);
7253 return;
7254 }
7255
7256 root_len = wcslen(root);
7257
7258 wcscpy(dest_path, root);
7259 if(root_len) {
7260 dest_path[root_len] = *L"\\";
7261 root_len += 1;
7262 }
7263 wcscpy(dest_path+root_len, rest);
7264}
7265
7266void _joinA(char *dest_path, const char *root, const char *rest) {
7267 /* join root and rest with a backslash */
7268 int root_len;
7269
7270 if(_is_absA(rest)) {
7271 strcpy(dest_path, rest);
7272 return;
7273 }
7274
7275 root_len = strlen(root);
7276
7277 strcpy(dest_path, root);
7278 if(root_len) {
7279 dest_path[root_len] = '\\';
7280 root_len += 1;
7281 }
7282 strcpy(dest_path+root_len, rest);
7283}
7284
7285int _check_dirW(WCHAR *src, WCHAR *dest)
7286{
7287 /* Return True if the path at src relative to dest is a directory */
7288 WIN32_FILE_ATTRIBUTE_DATA src_info;
7289 WCHAR dest_parent[MAX_PATH];
7290 WCHAR src_resolved[MAX_PATH] = L"";
7291
7292 /* dest_parent = os.path.dirname(dest) */
7293 wcscpy(dest_parent, dest);
7294 _dirnameW(dest_parent);
7295 /* src_resolved = os.path.join(dest_parent, src) */
7296 _joinW(src_resolved, dest_parent, src);
7297 return (
7298 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7299 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7300 );
7301}
7302
7303int _check_dirA(char *src, char *dest)
7304{
7305 /* Return True if the path at src relative to dest is a directory */
7306 WIN32_FILE_ATTRIBUTE_DATA src_info;
7307 char dest_parent[MAX_PATH];
7308 char src_resolved[MAX_PATH] = "";
7309
7310 /* dest_parent = os.path.dirname(dest) */
7311 strcpy(dest_parent, dest);
7312 _dirnameW(dest_parent);
7313 /* src_resolved = os.path.join(dest_parent, src) */
7314 _joinW(src_resolved, dest_parent, src);
7315 return (
7316 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7317 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7318 );
7319}
7320
Larry Hastings9cf065c2012-06-22 16:30:09 -07007321#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007322
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007323static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007324posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007325{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007326 path_t src;
7327 path_t dst;
7328 int dir_fd = DEFAULT_DIR_FD;
7329 int target_is_directory = 0;
7330 static char *keywords[] = {"src", "dst", "target_is_directory",
7331 "dir_fd", NULL};
7332 PyObject *return_value;
7333#ifdef MS_WINDOWS
7334 DWORD result;
7335#else
7336 int result;
7337#endif
7338
7339 memset(&src, 0, sizeof(src));
7340 src.argument_name = "src";
7341 memset(&dst, 0, sizeof(dst));
7342 dst.argument_name = "dst";
7343
7344#ifdef MS_WINDOWS
7345 if (!check_CreateSymbolicLink()) {
7346 PyErr_SetString(PyExc_NotImplementedError,
7347 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007348 return NULL;
7349 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007350 if (!win32_can_symlink) {
7351 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007352 return NULL;
7353 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007354#endif
7355
7356 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7357 keywords,
7358 path_converter, &src,
7359 path_converter, &dst,
7360 &target_is_directory,
7361#ifdef HAVE_SYMLINKAT
7362 dir_fd_converter, &dir_fd
7363#else
7364 dir_fd_unavailable, &dir_fd
7365#endif
7366 ))
7367 return NULL;
7368
7369 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7370 PyErr_SetString(PyExc_ValueError,
7371 "symlink: src and dst must be the same type");
7372 return_value = NULL;
7373 goto exit;
7374 }
7375
7376#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007377
Larry Hastings9cf065c2012-06-22 16:30:09 -07007378 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007379 if (dst.wide) {
7380 /* if src is a directory, ensure target_is_directory==1 */
7381 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007382 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7383 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007384 }
7385 else {
7386 /* if src is a directory, ensure target_is_directory==1 */
7387 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007388 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7389 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007390 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007391 Py_END_ALLOW_THREADS
7392
7393 if (!result) {
7394 return_value = win32_error_object("symlink", src.object);
7395 goto exit;
7396 }
7397
7398#else
7399
7400 Py_BEGIN_ALLOW_THREADS
7401#if HAVE_SYMLINKAT
7402 if (dir_fd != DEFAULT_DIR_FD)
7403 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7404 else
7405#endif
7406 result = symlink(src.narrow, dst.narrow);
7407 Py_END_ALLOW_THREADS
7408
7409 if (result) {
7410 return_value = path_error("symlink", &dst);
7411 goto exit;
7412 }
7413#endif
7414
7415 return_value = Py_None;
7416 Py_INCREF(Py_None);
7417 goto exit; /* silence "unused label" warning */
7418exit:
7419 path_cleanup(&src);
7420 path_cleanup(&dst);
7421 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007422}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007424#endif /* HAVE_SYMLINK */
7425
Larry Hastings9cf065c2012-06-22 16:30:09 -07007426
Brian Curtind40e6f72010-07-08 21:39:08 +00007427#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7428
Brian Curtind40e6f72010-07-08 21:39:08 +00007429static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007431{
7432 wchar_t *path;
7433 DWORD n_bytes_returned;
7434 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007435 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007436 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007437 HANDLE reparse_point_handle;
7438
7439 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7440 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7441 wchar_t *print_name;
7442
Larry Hastings9cf065c2012-06-22 16:30:09 -07007443 static char *keywords[] = {"path", "dir_fd", NULL};
7444
7445 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7446 &po,
7447 dir_fd_unavailable, &dir_fd
7448 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007449 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007450
Victor Stinnereb5657a2011-09-30 01:44:27 +02007451 path = PyUnicode_AsUnicode(po);
7452 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007453 return NULL;
7454
7455 /* First get a handle to the reparse point */
7456 Py_BEGIN_ALLOW_THREADS
7457 reparse_point_handle = CreateFileW(
7458 path,
7459 0,
7460 0,
7461 0,
7462 OPEN_EXISTING,
7463 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7464 0);
7465 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007466
Brian Curtind40e6f72010-07-08 21:39:08 +00007467 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007468 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007469
Brian Curtind40e6f72010-07-08 21:39:08 +00007470 Py_BEGIN_ALLOW_THREADS
7471 /* New call DeviceIoControl to read the reparse point */
7472 io_result = DeviceIoControl(
7473 reparse_point_handle,
7474 FSCTL_GET_REPARSE_POINT,
7475 0, 0, /* in buffer */
7476 target_buffer, sizeof(target_buffer),
7477 &n_bytes_returned,
7478 0 /* we're not using OVERLAPPED_IO */
7479 );
7480 CloseHandle(reparse_point_handle);
7481 Py_END_ALLOW_THREADS
7482
7483 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007484 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007485
7486 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7487 {
7488 PyErr_SetString(PyExc_ValueError,
7489 "not a symbolic link");
7490 return NULL;
7491 }
Brian Curtin74e45612010-07-09 15:58:59 +00007492 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7493 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7494
7495 result = PyUnicode_FromWideChar(print_name,
7496 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007497 return result;
7498}
7499
7500#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7501
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007502
Larry Hastings605a62d2012-06-24 04:33:36 -07007503static PyStructSequence_Field times_result_fields[] = {
7504 {"user", "user time"},
7505 {"system", "system time"},
7506 {"children_user", "user time of children"},
7507 {"children_system", "system time of children"},
7508 {"elapsed", "elapsed time since an arbitrary point in the past"},
7509 {NULL}
7510};
7511
7512PyDoc_STRVAR(times_result__doc__,
7513"times_result: Result from os.times().\n\n\
7514This object may be accessed either as a tuple of\n\
7515 (user, system, children_user, children_system, elapsed),\n\
7516or via the attributes user, system, children_user, children_system,\n\
7517and elapsed.\n\
7518\n\
7519See os.times for more information.");
7520
7521static PyStructSequence_Desc times_result_desc = {
7522 "times_result", /* name */
7523 times_result__doc__, /* doc */
7524 times_result_fields,
7525 5
7526};
7527
7528static PyTypeObject TimesResultType;
7529
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007530#ifdef MS_WINDOWS
7531#define HAVE_TIMES /* mandatory, for the method table */
7532#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007533
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007534#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007535
7536static PyObject *
7537build_times_result(double user, double system,
7538 double children_user, double children_system,
7539 double elapsed)
7540{
7541 PyObject *value = PyStructSequence_New(&TimesResultType);
7542 if (value == NULL)
7543 return NULL;
7544
7545#define SET(i, field) \
7546 { \
7547 PyObject *o = PyFloat_FromDouble(field); \
7548 if (!o) { \
7549 Py_DECREF(value); \
7550 return NULL; \
7551 } \
7552 PyStructSequence_SET_ITEM(value, i, o); \
7553 } \
7554
7555 SET(0, user);
7556 SET(1, system);
7557 SET(2, children_user);
7558 SET(3, children_system);
7559 SET(4, elapsed);
7560
7561#undef SET
7562
7563 return value;
7564}
7565
7566PyDoc_STRVAR(posix_times__doc__,
7567"times() -> times_result\n\n\
7568Return an object containing floating point numbers indicating process\n\
7569times. The object behaves like a named tuple with these fields:\n\
7570 (utime, stime, cutime, cstime, elapsed_time)");
7571
Guido van Rossumd48f2521997-12-05 22:19:34 +00007572#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7573static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007574system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007575{
7576 ULONG value = 0;
7577
7578 Py_BEGIN_ALLOW_THREADS
7579 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7580 Py_END_ALLOW_THREADS
7581
7582 return value;
7583}
7584
7585static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007586posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007587{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007588 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007589 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 (double)0 /* t.tms_utime / HZ */,
7591 (double)0 /* t.tms_stime / HZ */,
7592 (double)0 /* t.tms_cutime / HZ */,
7593 (double)0 /* t.tms_cstime / HZ */,
7594 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007595}
Larry Hastings605a62d2012-06-24 04:33:36 -07007596#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007597static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007598posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007599{
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 FILETIME create, exit, kernel, user;
7601 HANDLE hProc;
7602 hProc = GetCurrentProcess();
7603 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7604 /* The fields of a FILETIME structure are the hi and lo part
7605 of a 64-bit value expressed in 100 nanosecond units.
7606 1e7 is one second in such units; 1e-7 the inverse.
7607 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7608 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007609 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 (double)(user.dwHighDateTime*429.4967296 +
7611 user.dwLowDateTime*1e-7),
7612 (double)(kernel.dwHighDateTime*429.4967296 +
7613 kernel.dwLowDateTime*1e-7),
7614 (double)0,
7615 (double)0,
7616 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007617}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007618#else /* Neither Windows nor OS/2 */
7619#define NEED_TICKS_PER_SECOND
7620static long ticks_per_second = -1;
7621static PyObject *
7622posix_times(PyObject *self, PyObject *noargs)
7623{
7624 struct tms t;
7625 clock_t c;
7626 errno = 0;
7627 c = times(&t);
7628 if (c == (clock_t) -1)
7629 return posix_error();
7630 return build_times_result(
7631 (double)t.tms_utime / ticks_per_second,
7632 (double)t.tms_stime / ticks_per_second,
7633 (double)t.tms_cutime / ticks_per_second,
7634 (double)t.tms_cstime / ticks_per_second,
7635 (double)c / ticks_per_second);
7636}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007637#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007638
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007639#endif /* HAVE_TIMES */
7640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007641
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007642#ifdef HAVE_GETSID
7643PyDoc_STRVAR(posix_getsid__doc__,
7644"getsid(pid) -> sid\n\n\
7645Call the system call getsid().");
7646
7647static PyObject *
7648posix_getsid(PyObject *self, PyObject *args)
7649{
Victor Stinner8c62be82010-05-06 00:08:46 +00007650 pid_t pid;
7651 int sid;
7652 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7653 return NULL;
7654 sid = getsid(pid);
7655 if (sid < 0)
7656 return posix_error();
7657 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007658}
7659#endif /* HAVE_GETSID */
7660
7661
Guido van Rossumb6775db1994-08-01 11:34:53 +00007662#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007663PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007664"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007665Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007666
Barry Warsaw53699e91996-12-10 23:23:01 +00007667static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007668posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007669{
Victor Stinner8c62be82010-05-06 00:08:46 +00007670 if (setsid() < 0)
7671 return posix_error();
7672 Py_INCREF(Py_None);
7673 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007674}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007675#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007676
Guido van Rossumb6775db1994-08-01 11:34:53 +00007677#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007678PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007679"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007680Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007681
Barry Warsaw53699e91996-12-10 23:23:01 +00007682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007683posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007684{
Victor Stinner8c62be82010-05-06 00:08:46 +00007685 pid_t pid;
7686 int pgrp;
7687 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7688 return NULL;
7689 if (setpgid(pid, pgrp) < 0)
7690 return posix_error();
7691 Py_INCREF(Py_None);
7692 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007693}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007694#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007696
Guido van Rossumb6775db1994-08-01 11:34:53 +00007697#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007698PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007699"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007700Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007701
Barry Warsaw53699e91996-12-10 23:23:01 +00007702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007703posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007704{
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 int fd;
7706 pid_t pgid;
7707 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7708 return NULL;
7709 pgid = tcgetpgrp(fd);
7710 if (pgid < 0)
7711 return posix_error();
7712 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007713}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007714#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007716
Guido van Rossumb6775db1994-08-01 11:34:53 +00007717#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007718PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007719"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007720Set the process group associated with the terminal given by a fd.");
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_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007724{
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 int fd;
7726 pid_t pgid;
7727 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7728 return NULL;
7729 if (tcsetpgrp(fd, pgid) < 0)
7730 return posix_error();
7731 Py_INCREF(Py_None);
7732 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007733}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007734#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007735
Guido van Rossum687dd131993-05-17 08:34:16 +00007736/* Functions acting on file descriptors */
7737
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007738PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007739"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7740Open a file for low level IO. Returns a file handle (integer).\n\
7741\n\
7742If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7743 and path should be relative; path will then be relative to that directory.\n\
7744dir_fd may not be implemented on your platform.\n\
7745 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007746
Barry Warsaw53699e91996-12-10 23:23:01 +00007747static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007748posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007749{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007750 path_t path;
7751 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007753 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007755 PyObject *return_value = NULL;
7756 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007757
Larry Hastings9cf065c2012-06-22 16:30:09 -07007758 memset(&path, 0, sizeof(path));
7759 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7760 path_converter, &path,
7761 &flags, &mode,
7762#ifdef HAVE_OPENAT
7763 dir_fd_converter, &dir_fd
7764#else
7765 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007766#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007767 ))
7768 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007769
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007771#ifdef MS_WINDOWS
7772 if (path.wide)
7773 fd = _wopen(path.wide, flags, mode);
7774 else
7775#endif
7776#ifdef HAVE_OPENAT
7777 if (dir_fd != DEFAULT_DIR_FD)
7778 fd = openat(dir_fd, path.narrow, flags, mode);
7779 else
7780#endif
7781 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007783
Larry Hastings9cf065c2012-06-22 16:30:09 -07007784 if (fd == -1) {
7785#ifdef MS_WINDOWS
7786 /* force use of posix_error here for exact backwards compatibility */
7787 if (path.wide)
7788 return_value = posix_error();
7789 else
7790#endif
7791 return_value = path_error("open", &path);
7792 goto exit;
7793 }
7794
7795 return_value = PyLong_FromLong((long)fd);
7796
7797exit:
7798 path_cleanup(&path);
7799 return return_value;
7800}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007801
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007802PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007803"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007804Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007805
Barry Warsaw53699e91996-12-10 23:23:01 +00007806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007807posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007808{
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 int fd, res;
7810 if (!PyArg_ParseTuple(args, "i:close", &fd))
7811 return NULL;
7812 if (!_PyVerify_fd(fd))
7813 return posix_error();
7814 Py_BEGIN_ALLOW_THREADS
7815 res = close(fd);
7816 Py_END_ALLOW_THREADS
7817 if (res < 0)
7818 return posix_error();
7819 Py_INCREF(Py_None);
7820 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007821}
7822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007823
Victor Stinner8c62be82010-05-06 00:08:46 +00007824PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007825"closerange(fd_low, fd_high)\n\n\
7826Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7827
7828static PyObject *
7829posix_closerange(PyObject *self, PyObject *args)
7830{
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 int fd_from, fd_to, i;
7832 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7833 return NULL;
7834 Py_BEGIN_ALLOW_THREADS
7835 for (i = fd_from; i < fd_to; i++)
7836 if (_PyVerify_fd(i))
7837 close(i);
7838 Py_END_ALLOW_THREADS
7839 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007840}
7841
7842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007843PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007844"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007845Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007846
Barry Warsaw53699e91996-12-10 23:23:01 +00007847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007848posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007849{
Victor Stinner8c62be82010-05-06 00:08:46 +00007850 int fd;
7851 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7852 return NULL;
7853 if (!_PyVerify_fd(fd))
7854 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 if (fd < 0)
7857 return posix_error();
7858 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007859}
7860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007861
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007862PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007863"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007864Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007865
Barry Warsaw53699e91996-12-10 23:23:01 +00007866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007867posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007868{
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 int fd, fd2, res;
7870 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7871 return NULL;
7872 if (!_PyVerify_fd_dup2(fd, fd2))
7873 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 if (res < 0)
7876 return posix_error();
7877 Py_INCREF(Py_None);
7878 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007879}
7880
Ross Lagerwall7807c352011-03-17 20:20:30 +02007881#ifdef HAVE_LOCKF
7882PyDoc_STRVAR(posix_lockf__doc__,
7883"lockf(fd, cmd, len)\n\n\
7884Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7885fd is an open file descriptor.\n\
7886cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7887F_TEST.\n\
7888len specifies the section of the file to lock.");
7889
7890static PyObject *
7891posix_lockf(PyObject *self, PyObject *args)
7892{
7893 int fd, cmd, res;
7894 off_t len;
7895 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7896 &fd, &cmd, _parse_off_t, &len))
7897 return NULL;
7898
7899 Py_BEGIN_ALLOW_THREADS
7900 res = lockf(fd, cmd, len);
7901 Py_END_ALLOW_THREADS
7902
7903 if (res < 0)
7904 return posix_error();
7905
7906 Py_RETURN_NONE;
7907}
7908#endif
7909
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007910
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007911PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007912"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007913Set the current position of a file descriptor.\n\
7914Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007915
Barry Warsaw53699e91996-12-10 23:23:01 +00007916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007917posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007918{
Victor Stinner8c62be82010-05-06 00:08:46 +00007919 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007920#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007922#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007923 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007924#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007925 PyObject *posobj;
7926 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007928#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007929 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7930 switch (how) {
7931 case 0: how = SEEK_SET; break;
7932 case 1: how = SEEK_CUR; break;
7933 case 2: how = SEEK_END; break;
7934 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007935#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007936
Ross Lagerwall8e749672011-03-17 21:54:07 +02007937#if !defined(HAVE_LARGEFILE_SUPPORT)
7938 pos = PyLong_AsLong(posobj);
7939#else
7940 pos = PyLong_AsLongLong(posobj);
7941#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 if (PyErr_Occurred())
7943 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007944
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 if (!_PyVerify_fd(fd))
7946 return posix_error();
7947 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007948#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007950#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007952#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 Py_END_ALLOW_THREADS
7954 if (res < 0)
7955 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007956
7957#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007959#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007961#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007962}
7963
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007964
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007965PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07007966"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007967Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007968
Barry Warsaw53699e91996-12-10 23:23:01 +00007969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007970posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007971{
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 int fd, size;
7973 Py_ssize_t n;
7974 PyObject *buffer;
7975 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7976 return NULL;
7977 if (size < 0) {
7978 errno = EINVAL;
7979 return posix_error();
7980 }
7981 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7982 if (buffer == NULL)
7983 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007984 if (!_PyVerify_fd(fd)) {
7985 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007987 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 Py_BEGIN_ALLOW_THREADS
7989 n = read(fd, PyBytes_AS_STRING(buffer), size);
7990 Py_END_ALLOW_THREADS
7991 if (n < 0) {
7992 Py_DECREF(buffer);
7993 return posix_error();
7994 }
7995 if (n != size)
7996 _PyBytes_Resize(&buffer, n);
7997 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007998}
7999
Ross Lagerwall7807c352011-03-17 20:20:30 +02008000#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8001 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008002static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008003iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8004{
8005 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008006 Py_ssize_t blen, total = 0;
8007
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008008 *iov = PyMem_New(struct iovec, cnt);
8009 if (*iov == NULL) {
8010 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008011 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008012 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008013
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008014 *buf = PyMem_New(Py_buffer, cnt);
8015 if (*buf == NULL) {
8016 PyMem_Del(*iov);
8017 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008018 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008019 }
8020
8021 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008022 PyObject *item = PySequence_GetItem(seq, i);
8023 if (item == NULL)
8024 goto fail;
8025 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8026 Py_DECREF(item);
8027 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008028 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008029 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008030 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008031 blen = (*buf)[i].len;
8032 (*iov)[i].iov_len = blen;
8033 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008034 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008035 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008036
8037fail:
8038 PyMem_Del(*iov);
8039 for (j = 0; j < i; j++) {
8040 PyBuffer_Release(&(*buf)[j]);
8041 }
8042 PyMem_Del(*buf);
8043 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008044}
8045
8046static void
8047iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8048{
8049 int i;
8050 PyMem_Del(iov);
8051 for (i = 0; i < cnt; i++) {
8052 PyBuffer_Release(&buf[i]);
8053 }
8054 PyMem_Del(buf);
8055}
8056#endif
8057
Ross Lagerwall7807c352011-03-17 20:20:30 +02008058#ifdef HAVE_READV
8059PyDoc_STRVAR(posix_readv__doc__,
8060"readv(fd, buffers) -> bytesread\n\n\
8061Read from a file descriptor into a number of writable buffers. buffers\n\
8062is an arbitrary sequence of writable buffers.\n\
8063Returns the total number of bytes read.");
8064
8065static PyObject *
8066posix_readv(PyObject *self, PyObject *args)
8067{
8068 int fd, cnt;
8069 Py_ssize_t n;
8070 PyObject *seq;
8071 struct iovec *iov;
8072 Py_buffer *buf;
8073
8074 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8075 return NULL;
8076 if (!PySequence_Check(seq)) {
8077 PyErr_SetString(PyExc_TypeError,
8078 "readv() arg 2 must be a sequence");
8079 return NULL;
8080 }
8081 cnt = PySequence_Size(seq);
8082
8083 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
8084 return NULL;
8085
8086 Py_BEGIN_ALLOW_THREADS
8087 n = readv(fd, iov, cnt);
8088 Py_END_ALLOW_THREADS
8089
8090 iov_cleanup(iov, buf, cnt);
8091 return PyLong_FromSsize_t(n);
8092}
8093#endif
8094
8095#ifdef HAVE_PREAD
8096PyDoc_STRVAR(posix_pread__doc__,
8097"pread(fd, buffersize, offset) -> string\n\n\
8098Read from a file descriptor, fd, at a position of offset. It will read up\n\
8099to buffersize number of bytes. The file offset remains unchanged.");
8100
8101static PyObject *
8102posix_pread(PyObject *self, PyObject *args)
8103{
8104 int fd, size;
8105 off_t offset;
8106 Py_ssize_t n;
8107 PyObject *buffer;
8108 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8109 return NULL;
8110
8111 if (size < 0) {
8112 errno = EINVAL;
8113 return posix_error();
8114 }
8115 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8116 if (buffer == NULL)
8117 return NULL;
8118 if (!_PyVerify_fd(fd)) {
8119 Py_DECREF(buffer);
8120 return posix_error();
8121 }
8122 Py_BEGIN_ALLOW_THREADS
8123 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8124 Py_END_ALLOW_THREADS
8125 if (n < 0) {
8126 Py_DECREF(buffer);
8127 return posix_error();
8128 }
8129 if (n != size)
8130 _PyBytes_Resize(&buffer, n);
8131 return buffer;
8132}
8133#endif
8134
8135PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008136"write(fd, data) -> byteswritten\n\n\
8137Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008138
8139static PyObject *
8140posix_write(PyObject *self, PyObject *args)
8141{
8142 Py_buffer pbuf;
8143 int fd;
8144 Py_ssize_t size, len;
8145
8146 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8147 return NULL;
8148 if (!_PyVerify_fd(fd)) {
8149 PyBuffer_Release(&pbuf);
8150 return posix_error();
8151 }
8152 len = pbuf.len;
8153 Py_BEGIN_ALLOW_THREADS
8154#if defined(MS_WIN64) || defined(MS_WINDOWS)
8155 if (len > INT_MAX)
8156 len = INT_MAX;
8157 size = write(fd, pbuf.buf, (int)len);
8158#else
8159 size = write(fd, pbuf.buf, len);
8160#endif
8161 Py_END_ALLOW_THREADS
8162 PyBuffer_Release(&pbuf);
8163 if (size < 0)
8164 return posix_error();
8165 return PyLong_FromSsize_t(size);
8166}
8167
8168#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008169PyDoc_STRVAR(posix_sendfile__doc__,
8170"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8171sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8172 -> byteswritten\n\
8173Copy nbytes bytes from file descriptor in to file descriptor out.");
8174
8175static PyObject *
8176posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8177{
8178 int in, out;
8179 Py_ssize_t ret;
8180 off_t offset;
8181
8182#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8183#ifndef __APPLE__
8184 Py_ssize_t len;
8185#endif
8186 PyObject *headers = NULL, *trailers = NULL;
8187 Py_buffer *hbuf, *tbuf;
8188 off_t sbytes;
8189 struct sf_hdtr sf;
8190 int flags = 0;
8191 sf.headers = NULL;
8192 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008193 static char *keywords[] = {"out", "in",
8194 "offset", "count",
8195 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008196
8197#ifdef __APPLE__
8198 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008199 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008200#else
8201 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008202 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008203#endif
8204 &headers, &trailers, &flags))
8205 return NULL;
8206 if (headers != NULL) {
8207 if (!PySequence_Check(headers)) {
8208 PyErr_SetString(PyExc_TypeError,
8209 "sendfile() headers must be a sequence or None");
8210 return NULL;
8211 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008212 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008213 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008214 if (sf.hdr_cnt > 0 &&
8215 !(i = iov_setup(&(sf.headers), &hbuf,
8216 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008217 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008218#ifdef __APPLE__
8219 sbytes += i;
8220#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008221 }
8222 }
8223 if (trailers != NULL) {
8224 if (!PySequence_Check(trailers)) {
8225 PyErr_SetString(PyExc_TypeError,
8226 "sendfile() trailers must be a sequence or None");
8227 return NULL;
8228 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008229 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008230 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008231 if (sf.trl_cnt > 0 &&
8232 !(i = iov_setup(&(sf.trailers), &tbuf,
8233 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008234 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008235#ifdef __APPLE__
8236 sbytes += i;
8237#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008238 }
8239 }
8240
8241 Py_BEGIN_ALLOW_THREADS
8242#ifdef __APPLE__
8243 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8244#else
8245 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8246#endif
8247 Py_END_ALLOW_THREADS
8248
8249 if (sf.headers != NULL)
8250 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8251 if (sf.trailers != NULL)
8252 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8253
8254 if (ret < 0) {
8255 if ((errno == EAGAIN) || (errno == EBUSY)) {
8256 if (sbytes != 0) {
8257 // some data has been sent
8258 goto done;
8259 }
8260 else {
8261 // no data has been sent; upper application is supposed
8262 // to retry on EAGAIN or EBUSY
8263 return posix_error();
8264 }
8265 }
8266 return posix_error();
8267 }
8268 goto done;
8269
8270done:
8271 #if !defined(HAVE_LARGEFILE_SUPPORT)
8272 return Py_BuildValue("l", sbytes);
8273 #else
8274 return Py_BuildValue("L", sbytes);
8275 #endif
8276
8277#else
8278 Py_ssize_t count;
8279 PyObject *offobj;
8280 static char *keywords[] = {"out", "in",
8281 "offset", "count", NULL};
8282 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8283 keywords, &out, &in, &offobj, &count))
8284 return NULL;
8285#ifdef linux
8286 if (offobj == Py_None) {
8287 Py_BEGIN_ALLOW_THREADS
8288 ret = sendfile(out, in, NULL, count);
8289 Py_END_ALLOW_THREADS
8290 if (ret < 0)
8291 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008292 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008293 }
8294#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008295 if (!_parse_off_t(offobj, &offset))
8296 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008297 Py_BEGIN_ALLOW_THREADS
8298 ret = sendfile(out, in, &offset, count);
8299 Py_END_ALLOW_THREADS
8300 if (ret < 0)
8301 return posix_error();
8302 return Py_BuildValue("n", ret);
8303#endif
8304}
8305#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008306
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008307PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008308"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008309Like stat(), but for an open file descriptor.\n\
8310Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008311
Barry Warsaw53699e91996-12-10 23:23:01 +00008312static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008313posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008314{
Victor Stinner8c62be82010-05-06 00:08:46 +00008315 int fd;
8316 STRUCT_STAT st;
8317 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008318 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008319 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008320#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008321 /* on OpenVMS we must ensure that all bytes are written to the file */
8322 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008323#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008324 Py_BEGIN_ALLOW_THREADS
8325 res = FSTAT(fd, &st);
8326 Py_END_ALLOW_THREADS
8327 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008328#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008330#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008332#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008333 }
Tim Peters5aa91602002-01-30 05:46:57 +00008334
Victor Stinner4195b5c2012-02-08 23:03:19 +01008335 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008336}
8337
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008338PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008339"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008340Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008341connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008342
8343static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008344posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008345{
Victor Stinner8c62be82010-05-06 00:08:46 +00008346 int fd;
8347 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8348 return NULL;
8349 if (!_PyVerify_fd(fd))
8350 return PyBool_FromLong(0);
8351 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008352}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008353
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008354#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008355PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008356"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008357Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008358
Barry Warsaw53699e91996-12-10 23:23:01 +00008359static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008360posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008361{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008362#if defined(PYOS_OS2)
8363 HFILE read, write;
8364 APIRET rc;
8365
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008366 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008367 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008368 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008369
8370 return Py_BuildValue("(ii)", read, write);
8371#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008372#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008373 int fds[2];
8374 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008375 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 if (res != 0)
8377 return posix_error();
8378 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008379#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 HANDLE read, write;
8381 int read_fd, write_fd;
8382 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008383 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008384 if (!ok)
8385 return win32_error("CreatePipe", NULL);
8386 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8387 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8388 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008389#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008390#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008391}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008392#endif /* HAVE_PIPE */
8393
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008394#ifdef HAVE_PIPE2
8395PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008396"pipe2(flags) -> (read_end, write_end)\n\n\
8397Create a pipe with flags set atomically.\n\
8398flags can be constructed by ORing together one or more of these values:\n\
8399O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008400");
8401
8402static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008403posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008404{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008405 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008406 int fds[2];
8407 int res;
8408
Serhiy Storchaka9101e232013-01-19 12:41:45 +02008409 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008410 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008411 return NULL;
8412
8413 res = pipe2(fds, flags);
8414 if (res != 0)
8415 return posix_error();
8416 return Py_BuildValue("(ii)", fds[0], fds[1]);
8417}
8418#endif /* HAVE_PIPE2 */
8419
Ross Lagerwall7807c352011-03-17 20:20:30 +02008420#ifdef HAVE_WRITEV
8421PyDoc_STRVAR(posix_writev__doc__,
8422"writev(fd, buffers) -> byteswritten\n\n\
8423Write the contents of buffers to a file descriptor, where buffers is an\n\
8424arbitrary sequence of buffers.\n\
8425Returns the total bytes written.");
8426
8427static PyObject *
8428posix_writev(PyObject *self, PyObject *args)
8429{
8430 int fd, cnt;
8431 Py_ssize_t res;
8432 PyObject *seq;
8433 struct iovec *iov;
8434 Py_buffer *buf;
8435 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8436 return NULL;
8437 if (!PySequence_Check(seq)) {
8438 PyErr_SetString(PyExc_TypeError,
8439 "writev() arg 2 must be a sequence");
8440 return NULL;
8441 }
8442 cnt = PySequence_Size(seq);
8443
8444 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8445 return NULL;
8446 }
8447
8448 Py_BEGIN_ALLOW_THREADS
8449 res = writev(fd, iov, cnt);
8450 Py_END_ALLOW_THREADS
8451
8452 iov_cleanup(iov, buf, cnt);
8453 return PyLong_FromSsize_t(res);
8454}
8455#endif
8456
8457#ifdef HAVE_PWRITE
8458PyDoc_STRVAR(posix_pwrite__doc__,
8459"pwrite(fd, string, offset) -> byteswritten\n\n\
8460Write string to a file descriptor, fd, from offset, leaving the file\n\
8461offset unchanged.");
8462
8463static PyObject *
8464posix_pwrite(PyObject *self, PyObject *args)
8465{
8466 Py_buffer pbuf;
8467 int fd;
8468 off_t offset;
8469 Py_ssize_t size;
8470
8471 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8472 return NULL;
8473
8474 if (!_PyVerify_fd(fd)) {
8475 PyBuffer_Release(&pbuf);
8476 return posix_error();
8477 }
8478 Py_BEGIN_ALLOW_THREADS
8479 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8480 Py_END_ALLOW_THREADS
8481 PyBuffer_Release(&pbuf);
8482 if (size < 0)
8483 return posix_error();
8484 return PyLong_FromSsize_t(size);
8485}
8486#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008487
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008488#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008489PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008490"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8491Create a FIFO (a POSIX named pipe).\n\
8492\n\
8493If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8494 and path should be relative; path will then be relative to that directory.\n\
8495dir_fd may not be implemented on your platform.\n\
8496 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008497
Barry Warsaw53699e91996-12-10 23:23:01 +00008498static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008499posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008500{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008501 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008503 int dir_fd = DEFAULT_DIR_FD;
8504 int result;
8505 PyObject *return_value = NULL;
8506 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8507
8508 memset(&path, 0, sizeof(path));
8509 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8510 path_converter, &path,
8511 &mode,
8512#ifdef HAVE_MKFIFOAT
8513 dir_fd_converter, &dir_fd
8514#else
8515 dir_fd_unavailable, &dir_fd
8516#endif
8517 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008519
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008521#ifdef HAVE_MKFIFOAT
8522 if (dir_fd != DEFAULT_DIR_FD)
8523 result = mkfifoat(dir_fd, path.narrow, mode);
8524 else
8525#endif
8526 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008527 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008528
8529 if (result < 0) {
8530 return_value = posix_error();
8531 goto exit;
8532 }
8533
8534 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008536
8537exit:
8538 path_cleanup(&path);
8539 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008540}
8541#endif
8542
Neal Norwitz11690112002-07-30 01:08:28 +00008543#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008544PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008545"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008546Create a filesystem node (file, device special file or named pipe)\n\
8547named filename. mode specifies both the permissions to use and the\n\
8548type of node to be created, being combined (bitwise OR) with one of\n\
8549S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008550device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008551os.makedev()), otherwise it is ignored.\n\
8552\n\
8553If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8554 and path should be relative; path will then be relative to that directory.\n\
8555dir_fd may not be implemented on your platform.\n\
8556 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008557
8558
8559static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008560posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008561{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008562 path_t path;
8563 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008564 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008565 int dir_fd = DEFAULT_DIR_FD;
8566 int result;
8567 PyObject *return_value = NULL;
8568 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8569
8570 memset(&path, 0, sizeof(path));
8571 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8572 path_converter, &path,
8573 &mode, &device,
8574#ifdef HAVE_MKNODAT
8575 dir_fd_converter, &dir_fd
8576#else
8577 dir_fd_unavailable, &dir_fd
8578#endif
8579 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008581
Victor Stinner8c62be82010-05-06 00:08:46 +00008582 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008583#ifdef HAVE_MKNODAT
8584 if (dir_fd != DEFAULT_DIR_FD)
8585 result = mknodat(dir_fd, path.narrow, mode, device);
8586 else
8587#endif
8588 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008589 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008590
8591 if (result < 0) {
8592 return_value = posix_error();
8593 goto exit;
8594 }
8595
8596 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008597 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008598
Larry Hastings9cf065c2012-06-22 16:30:09 -07008599exit:
8600 path_cleanup(&path);
8601 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008602}
8603#endif
8604
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008605#ifdef HAVE_DEVICE_MACROS
8606PyDoc_STRVAR(posix_major__doc__,
8607"major(device) -> major number\n\
8608Extracts a device major number from a raw device number.");
8609
8610static PyObject *
8611posix_major(PyObject *self, PyObject *args)
8612{
Victor Stinner8c62be82010-05-06 00:08:46 +00008613 int device;
8614 if (!PyArg_ParseTuple(args, "i:major", &device))
8615 return NULL;
8616 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008617}
8618
8619PyDoc_STRVAR(posix_minor__doc__,
8620"minor(device) -> minor number\n\
8621Extracts a device minor number from a raw device number.");
8622
8623static PyObject *
8624posix_minor(PyObject *self, PyObject *args)
8625{
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 int device;
8627 if (!PyArg_ParseTuple(args, "i:minor", &device))
8628 return NULL;
8629 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008630}
8631
8632PyDoc_STRVAR(posix_makedev__doc__,
8633"makedev(major, minor) -> device number\n\
8634Composes a raw device number from the major and minor device numbers.");
8635
8636static PyObject *
8637posix_makedev(PyObject *self, PyObject *args)
8638{
Victor Stinner8c62be82010-05-06 00:08:46 +00008639 int major, minor;
8640 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8641 return NULL;
8642 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008643}
8644#endif /* device macros */
8645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008646
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008647#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008648PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008649"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008650Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008651
Barry Warsaw53699e91996-12-10 23:23:01 +00008652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008653posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008654{
Victor Stinner8c62be82010-05-06 00:08:46 +00008655 int fd;
8656 off_t length;
8657 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008658
Ross Lagerwall7807c352011-03-17 20:20:30 +02008659 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008660 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008661
Victor Stinner8c62be82010-05-06 00:08:46 +00008662 Py_BEGIN_ALLOW_THREADS
8663 res = ftruncate(fd, length);
8664 Py_END_ALLOW_THREADS
8665 if (res < 0)
8666 return posix_error();
8667 Py_INCREF(Py_None);
8668 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008669}
8670#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008671
Ross Lagerwall7807c352011-03-17 20:20:30 +02008672#ifdef HAVE_TRUNCATE
8673PyDoc_STRVAR(posix_truncate__doc__,
8674"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008675Truncate the file given by path to length bytes.\n\
8676On some platforms, path may also be specified as an open file descriptor.\n\
8677 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008678
8679static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008680posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008681{
Georg Brandl306336b2012-06-24 12:55:33 +02008682 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008683 off_t length;
8684 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008685 PyObject *result = NULL;
8686 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008687
Georg Brandl306336b2012-06-24 12:55:33 +02008688 memset(&path, 0, sizeof(path));
8689#ifdef HAVE_FTRUNCATE
8690 path.allow_fd = 1;
8691#endif
8692 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8693 path_converter, &path,
8694 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008695 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008696
8697 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008698#ifdef HAVE_FTRUNCATE
8699 if (path.fd != -1)
8700 res = ftruncate(path.fd, length);
8701 else
8702#endif
8703 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008704 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008705 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008706 result = path_posix_error("truncate", &path);
8707 else {
8708 Py_INCREF(Py_None);
8709 result = Py_None;
8710 }
8711 path_cleanup(&path);
8712 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008713}
8714#endif
8715
8716#ifdef HAVE_POSIX_FALLOCATE
8717PyDoc_STRVAR(posix_posix_fallocate__doc__,
8718"posix_fallocate(fd, offset, len)\n\n\
8719Ensures that enough disk space is allocated for the file specified by fd\n\
8720starting from offset and continuing for len bytes.");
8721
8722static PyObject *
8723posix_posix_fallocate(PyObject *self, PyObject *args)
8724{
8725 off_t len, offset;
8726 int res, fd;
8727
8728 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8729 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8730 return NULL;
8731
8732 Py_BEGIN_ALLOW_THREADS
8733 res = posix_fallocate(fd, offset, len);
8734 Py_END_ALLOW_THREADS
8735 if (res != 0) {
8736 errno = res;
8737 return posix_error();
8738 }
8739 Py_RETURN_NONE;
8740}
8741#endif
8742
8743#ifdef HAVE_POSIX_FADVISE
8744PyDoc_STRVAR(posix_posix_fadvise__doc__,
8745"posix_fadvise(fd, offset, len, advice)\n\n\
8746Announces an intention to access data in a specific pattern thus allowing\n\
8747the kernel to make optimizations.\n\
8748The advice applies to the region of the file specified by fd starting at\n\
8749offset and continuing for len bytes.\n\
8750advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8751POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8752POSIX_FADV_DONTNEED.");
8753
8754static PyObject *
8755posix_posix_fadvise(PyObject *self, PyObject *args)
8756{
8757 off_t len, offset;
8758 int res, fd, advice;
8759
8760 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8761 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8762 return NULL;
8763
8764 Py_BEGIN_ALLOW_THREADS
8765 res = posix_fadvise(fd, offset, len, advice);
8766 Py_END_ALLOW_THREADS
8767 if (res != 0) {
8768 errno = res;
8769 return posix_error();
8770 }
8771 Py_RETURN_NONE;
8772}
8773#endif
8774
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008775#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008776PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008777"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008778Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008779
Fred Drake762e2061999-08-26 17:23:54 +00008780/* Save putenv() parameters as values here, so we can collect them when they
8781 * get re-set with another call for the same key. */
8782static PyObject *posix_putenv_garbage;
8783
Tim Peters5aa91602002-01-30 05:46:57 +00008784static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008785posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008786{
Victor Stinner84ae1182010-05-06 22:05:07 +00008787 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008788#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008789 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008790 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008791
Victor Stinner8c62be82010-05-06 00:08:46 +00008792 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008793 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008794 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008795 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008796
Victor Stinner65170952011-11-22 22:16:17 +01008797 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008798 if (newstr == NULL) {
8799 PyErr_NoMemory();
8800 goto error;
8801 }
Victor Stinner65170952011-11-22 22:16:17 +01008802 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8803 PyErr_Format(PyExc_ValueError,
8804 "the environment variable is longer than %u characters",
8805 _MAX_ENV);
8806 goto error;
8807 }
8808
Victor Stinner8c62be82010-05-06 00:08:46 +00008809 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008810 if (newenv == NULL)
8811 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008812 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008813 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008814 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008815 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008816#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008817 PyObject *os1, *os2;
8818 char *s1, *s2;
8819 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008820
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008821 if (!PyArg_ParseTuple(args,
8822 "O&O&:putenv",
8823 PyUnicode_FSConverter, &os1,
8824 PyUnicode_FSConverter, &os2))
8825 return NULL;
8826 s1 = PyBytes_AsString(os1);
8827 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008828
Victor Stinner65170952011-11-22 22:16:17 +01008829 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008830 if (newstr == NULL) {
8831 PyErr_NoMemory();
8832 goto error;
8833 }
8834
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008836 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008838 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008840#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008841
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 /* Install the first arg and newstr in posix_putenv_garbage;
8843 * this will cause previous value to be collected. This has to
8844 * happen after the real putenv() call because the old value
8845 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008846 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 /* really not much we can do; just leak */
8848 PyErr_Clear();
8849 }
8850 else {
8851 Py_DECREF(newstr);
8852 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008853
Martin v. Löwis011e8422009-05-05 04:43:17 +00008854#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 Py_DECREF(os1);
8856 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008857#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008858 Py_RETURN_NONE;
8859
8860error:
8861#ifndef MS_WINDOWS
8862 Py_DECREF(os1);
8863 Py_DECREF(os2);
8864#endif
8865 Py_XDECREF(newstr);
8866 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008867}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008868#endif /* putenv */
8869
Guido van Rossumc524d952001-10-19 01:31:59 +00008870#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008871PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008872"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008873Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008874
8875static PyObject *
8876posix_unsetenv(PyObject *self, PyObject *args)
8877{
Victor Stinner65170952011-11-22 22:16:17 +01008878 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008879#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008880 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008881#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008882
8883 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008884
Victor Stinner65170952011-11-22 22:16:17 +01008885 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008886 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008887
Victor Stinner984890f2011-11-24 13:53:38 +01008888#ifdef HAVE_BROKEN_UNSETENV
8889 unsetenv(PyBytes_AS_STRING(name));
8890#else
Victor Stinner65170952011-11-22 22:16:17 +01008891 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008892 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008893 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008894 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008895 }
Victor Stinner984890f2011-11-24 13:53:38 +01008896#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008897
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 /* Remove the key from posix_putenv_garbage;
8899 * this will cause it to be collected. This has to
8900 * happen after the real unsetenv() call because the
8901 * old value was still accessible until then.
8902 */
Victor Stinner65170952011-11-22 22:16:17 +01008903 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 /* really not much we can do; just leak */
8905 PyErr_Clear();
8906 }
Victor Stinner65170952011-11-22 22:16:17 +01008907 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008908 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008909}
8910#endif /* unsetenv */
8911
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008912PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008913"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008914Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008915
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008917posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008918{
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 int code;
8920 char *message;
8921 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8922 return NULL;
8923 message = strerror(code);
8924 if (message == NULL) {
8925 PyErr_SetString(PyExc_ValueError,
8926 "strerror() argument out of range");
8927 return NULL;
8928 }
Victor Stinner1b579672011-12-17 05:47:23 +01008929 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008930}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008931
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008932
Guido van Rossumc9641791998-08-04 15:26:23 +00008933#ifdef HAVE_SYS_WAIT_H
8934
Fred Drake106c1a02002-04-23 15:58:02 +00008935#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008936PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008937"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008938Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008939
8940static PyObject *
8941posix_WCOREDUMP(PyObject *self, PyObject *args)
8942{
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 WAIT_TYPE status;
8944 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008945
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8947 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008948
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008950}
8951#endif /* WCOREDUMP */
8952
8953#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008954PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008955"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008956Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008957job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008958
8959static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008960posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008961{
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 WAIT_TYPE status;
8963 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008964
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8966 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008967
Victor Stinner8c62be82010-05-06 00:08:46 +00008968 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008969}
8970#endif /* WIFCONTINUED */
8971
Guido van Rossumc9641791998-08-04 15:26:23 +00008972#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008973PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008974"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008975Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008976
8977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008978posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008979{
Victor Stinner8c62be82010-05-06 00:08:46 +00008980 WAIT_TYPE status;
8981 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008982
Victor Stinner8c62be82010-05-06 00:08:46 +00008983 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8984 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008985
Victor Stinner8c62be82010-05-06 00:08:46 +00008986 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008987}
8988#endif /* WIFSTOPPED */
8989
8990#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008991PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008992"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008993Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008994
8995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008996posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008997{
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 WAIT_TYPE status;
8999 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009000
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9002 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009003
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009005}
9006#endif /* WIFSIGNALED */
9007
9008#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009009PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009010"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009011Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009012system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009013
9014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009015posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009016{
Victor Stinner8c62be82010-05-06 00:08:46 +00009017 WAIT_TYPE status;
9018 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009019
Victor Stinner8c62be82010-05-06 00:08:46 +00009020 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9021 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009022
Victor Stinner8c62be82010-05-06 00:08:46 +00009023 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009024}
9025#endif /* WIFEXITED */
9026
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009027#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009028PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009029"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009030Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009031
9032static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009033posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009034{
Victor Stinner8c62be82010-05-06 00:08:46 +00009035 WAIT_TYPE status;
9036 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009037
Victor Stinner8c62be82010-05-06 00:08:46 +00009038 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9039 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009040
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009042}
9043#endif /* WEXITSTATUS */
9044
9045#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009046PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009047"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009048Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009049value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009050
9051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009052posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009053{
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 WAIT_TYPE status;
9055 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009056
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9058 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009059
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009061}
9062#endif /* WTERMSIG */
9063
9064#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009065PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009066"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009067Return the signal that stopped the process that provided\n\
9068the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009069
9070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009071posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009072{
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 WAIT_TYPE status;
9074 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009075
Victor Stinner8c62be82010-05-06 00:08:46 +00009076 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9077 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009078
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009080}
9081#endif /* WSTOPSIG */
9082
9083#endif /* HAVE_SYS_WAIT_H */
9084
9085
Thomas Wouters477c8d52006-05-27 19:21:47 +00009086#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009087#ifdef _SCO_DS
9088/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9089 needed definitions in sys/statvfs.h */
9090#define _SVID3
9091#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009092#include <sys/statvfs.h>
9093
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009094static PyObject*
9095_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9097 if (v == NULL)
9098 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009099
9100#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009101 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9102 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9103 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9104 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9105 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9106 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9107 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9108 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9109 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9110 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009111#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009112 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9113 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9114 PyStructSequence_SET_ITEM(v, 2,
9115 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9116 PyStructSequence_SET_ITEM(v, 3,
9117 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9118 PyStructSequence_SET_ITEM(v, 4,
9119 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9120 PyStructSequence_SET_ITEM(v, 5,
9121 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9122 PyStructSequence_SET_ITEM(v, 6,
9123 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9124 PyStructSequence_SET_ITEM(v, 7,
9125 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9126 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9127 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009128#endif
9129
Victor Stinner8c62be82010-05-06 00:08:46 +00009130 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009131}
9132
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009133PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009134"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009135Perform an fstatvfs system call on the given fd.\n\
9136Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009137
9138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009139posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009140{
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 int fd, res;
9142 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009143
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9145 return NULL;
9146 Py_BEGIN_ALLOW_THREADS
9147 res = fstatvfs(fd, &st);
9148 Py_END_ALLOW_THREADS
9149 if (res != 0)
9150 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009151
Victor Stinner8c62be82010-05-06 00:08:46 +00009152 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009153}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009154#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009155
9156
Thomas Wouters477c8d52006-05-27 19:21:47 +00009157#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009158#include <sys/statvfs.h>
9159
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009160PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009161"statvfs(path)\n\n\
9162Perform a statvfs system call on the given path.\n\
9163\n\
9164path may always be specified as a string.\n\
9165On some platforms, path may also be specified as an open file descriptor.\n\
9166 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009167
9168static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009169posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009170{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009171 static char *keywords[] = {"path", NULL};
9172 path_t path;
9173 int result;
9174 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009175 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009176
Larry Hastings9cf065c2012-06-22 16:30:09 -07009177 memset(&path, 0, sizeof(path));
9178#ifdef HAVE_FSTATVFS
9179 path.allow_fd = 1;
9180#endif
9181 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9182 path_converter, &path
9183 ))
9184 return NULL;
9185
9186 Py_BEGIN_ALLOW_THREADS
9187#ifdef HAVE_FSTATVFS
9188 if (path.fd != -1) {
9189#ifdef __APPLE__
9190 /* handle weak-linking on Mac OS X 10.3 */
9191 if (fstatvfs == NULL) {
9192 fd_specified("statvfs", path.fd);
9193 goto exit;
9194 }
9195#endif
9196 result = fstatvfs(path.fd, &st);
9197 }
9198 else
9199#endif
9200 result = statvfs(path.narrow, &st);
9201 Py_END_ALLOW_THREADS
9202
9203 if (result) {
9204 return_value = path_posix_error("statvfs", &path);
9205 goto exit;
9206 }
9207
9208 return_value = _pystatvfs_fromstructstatvfs(st);
9209
9210exit:
9211 path_cleanup(&path);
9212 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009213}
9214#endif /* HAVE_STATVFS */
9215
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009216#ifdef MS_WINDOWS
9217PyDoc_STRVAR(win32__getdiskusage__doc__,
9218"_getdiskusage(path) -> (total, free)\n\n\
9219Return disk usage statistics about the given path as (total, free) tuple.");
9220
9221static PyObject *
9222win32__getdiskusage(PyObject *self, PyObject *args)
9223{
9224 BOOL retval;
9225 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009226 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009227
Victor Stinner6139c1b2011-11-09 22:14:14 +01009228 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009229 return NULL;
9230
9231 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009232 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009233 Py_END_ALLOW_THREADS
9234 if (retval == 0)
9235 return PyErr_SetFromWindowsErr(0);
9236
9237 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9238}
9239#endif
9240
9241
Fred Drakec9680921999-12-13 16:37:25 +00009242/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9243 * It maps strings representing configuration variable names to
9244 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009245 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009246 * rarely-used constants. There are three separate tables that use
9247 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009248 *
9249 * This code is always included, even if none of the interfaces that
9250 * need it are included. The #if hackery needed to avoid it would be
9251 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009252 */
9253struct constdef {
9254 char *name;
9255 long value;
9256};
9257
Fred Drake12c6e2d1999-12-14 21:25:03 +00009258static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009259conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009260 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009261{
Christian Heimes217cfd12007-12-02 14:31:20 +00009262 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009263 *valuep = PyLong_AS_LONG(arg);
9264 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009265 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009266 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009267 /* look up the value in the table using a binary search */
9268 size_t lo = 0;
9269 size_t mid;
9270 size_t hi = tablesize;
9271 int cmp;
9272 const char *confname;
9273 if (!PyUnicode_Check(arg)) {
9274 PyErr_SetString(PyExc_TypeError,
9275 "configuration names must be strings or integers");
9276 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009277 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009278 confname = _PyUnicode_AsString(arg);
9279 if (confname == NULL)
9280 return 0;
9281 while (lo < hi) {
9282 mid = (lo + hi) / 2;
9283 cmp = strcmp(confname, table[mid].name);
9284 if (cmp < 0)
9285 hi = mid;
9286 else if (cmp > 0)
9287 lo = mid + 1;
9288 else {
9289 *valuep = table[mid].value;
9290 return 1;
9291 }
9292 }
9293 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9294 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009296}
9297
9298
9299#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9300static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009301#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009302 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009303#endif
9304#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009306#endif
Fred Drakec9680921999-12-13 16:37:25 +00009307#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009309#endif
9310#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009312#endif
9313#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009315#endif
9316#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009318#endif
9319#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009321#endif
9322#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009323 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009324#endif
9325#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009327#endif
9328#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009330#endif
9331#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009333#endif
9334#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009335 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009336#endif
9337#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009339#endif
9340#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009342#endif
9343#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009345#endif
9346#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009347 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009348#endif
9349#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009351#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009352#ifdef _PC_ACL_ENABLED
9353 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9354#endif
9355#ifdef _PC_MIN_HOLE_SIZE
9356 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9357#endif
9358#ifdef _PC_ALLOC_SIZE_MIN
9359 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9360#endif
9361#ifdef _PC_REC_INCR_XFER_SIZE
9362 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9363#endif
9364#ifdef _PC_REC_MAX_XFER_SIZE
9365 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9366#endif
9367#ifdef _PC_REC_MIN_XFER_SIZE
9368 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9369#endif
9370#ifdef _PC_REC_XFER_ALIGN
9371 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9372#endif
9373#ifdef _PC_SYMLINK_MAX
9374 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9375#endif
9376#ifdef _PC_XATTR_ENABLED
9377 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9378#endif
9379#ifdef _PC_XATTR_EXISTS
9380 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9381#endif
9382#ifdef _PC_TIMESTAMP_RESOLUTION
9383 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9384#endif
Fred Drakec9680921999-12-13 16:37:25 +00009385};
9386
Fred Drakec9680921999-12-13 16:37:25 +00009387static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009388conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009389{
9390 return conv_confname(arg, valuep, posix_constants_pathconf,
9391 sizeof(posix_constants_pathconf)
9392 / sizeof(struct constdef));
9393}
9394#endif
9395
9396#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009397PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009398"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009399Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009400If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009401
9402static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009403posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009404{
9405 PyObject *result = NULL;
9406 int name, fd;
9407
Fred Drake12c6e2d1999-12-14 21:25:03 +00009408 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9409 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009410 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009411
Stefan Krah0e803b32010-11-26 16:16:47 +00009412 errno = 0;
9413 limit = fpathconf(fd, name);
9414 if (limit == -1 && errno != 0)
9415 posix_error();
9416 else
9417 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009418 }
9419 return result;
9420}
9421#endif
9422
9423
9424#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009425PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009426"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009427Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009428If there is no limit, return -1.\n\
9429On some platforms, path may also be specified as an open file descriptor.\n\
9430 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009431
9432static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009433posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009434{
Georg Brandl306336b2012-06-24 12:55:33 +02009435 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009436 PyObject *result = NULL;
9437 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009438 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009439
Georg Brandl306336b2012-06-24 12:55:33 +02009440 memset(&path, 0, sizeof(path));
9441#ifdef HAVE_FPATHCONF
9442 path.allow_fd = 1;
9443#endif
9444 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9445 path_converter, &path,
9446 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009448
Victor Stinner8c62be82010-05-06 00:08:46 +00009449 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009450#ifdef HAVE_FPATHCONF
9451 if (path.fd != -1)
9452 limit = fpathconf(path.fd, name);
9453 else
9454#endif
9455 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 if (limit == -1 && errno != 0) {
9457 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009458 /* could be a path or name problem */
9459 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009460 else
Georg Brandl306336b2012-06-24 12:55:33 +02009461 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 }
9463 else
9464 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009465 }
Georg Brandl306336b2012-06-24 12:55:33 +02009466 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009467 return result;
9468}
9469#endif
9470
9471#ifdef HAVE_CONFSTR
9472static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009473#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009475#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009476#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009477 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009478#endif
9479#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009481#endif
Fred Draked86ed291999-12-15 15:34:33 +00009482#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009483 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009484#endif
9485#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009486 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009487#endif
9488#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009490#endif
9491#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009493#endif
Fred Drakec9680921999-12-13 16:37:25 +00009494#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009496#endif
9497#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009499#endif
9500#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009502#endif
9503#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009505#endif
9506#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009508#endif
9509#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009511#endif
9512#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009514#endif
9515#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009517#endif
Fred Draked86ed291999-12-15 15:34:33 +00009518#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009520#endif
Fred Drakec9680921999-12-13 16:37:25 +00009521#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009523#endif
Fred Draked86ed291999-12-15 15:34:33 +00009524#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009526#endif
9527#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009529#endif
9530#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009532#endif
9533#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009535#endif
Fred Drakec9680921999-12-13 16:37:25 +00009536#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009538#endif
9539#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009541#endif
9542#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
9572#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
9575#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
Fred Draked86ed291999-12-15 15:34:33 +00009584#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009586#endif
9587#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009589#endif
9590#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009592#endif
9593#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009595#endif
9596#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009598#endif
9599#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009601#endif
9602#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009604#endif
9605#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009607#endif
9608#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009610#endif
9611#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009613#endif
9614#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009616#endif
9617#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009619#endif
9620#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009622#endif
Fred Drakec9680921999-12-13 16:37:25 +00009623};
9624
9625static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009626conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009627{
9628 return conv_confname(arg, valuep, posix_constants_confstr,
9629 sizeof(posix_constants_confstr)
9630 / sizeof(struct constdef));
9631}
9632
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009633PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009634"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009635Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009636
9637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009638posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009639{
9640 PyObject *result = NULL;
9641 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009642 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009643 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009644
Victor Stinnercb043522010-09-10 23:49:04 +00009645 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9646 return NULL;
9647
9648 errno = 0;
9649 len = confstr(name, buffer, sizeof(buffer));
9650 if (len == 0) {
9651 if (errno) {
9652 posix_error();
9653 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009654 }
9655 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009656 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009657 }
9658 }
Victor Stinnercb043522010-09-10 23:49:04 +00009659
9660 if ((unsigned int)len >= sizeof(buffer)) {
9661 char *buf = PyMem_Malloc(len);
9662 if (buf == NULL)
9663 return PyErr_NoMemory();
9664 confstr(name, buf, len);
9665 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9666 PyMem_Free(buf);
9667 }
9668 else
9669 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009670 return result;
9671}
9672#endif
9673
9674
9675#ifdef HAVE_SYSCONF
9676static struct constdef posix_constants_sysconf[] = {
9677#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
9680#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
Fred Draked86ed291999-12-15 15:34:33 +00009707#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009709#endif
9710#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009712#endif
Fred Drakec9680921999-12-13 16:37:25 +00009713#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
Fred Drakec9680921999-12-13 16:37:25 +00009716#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
9722#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
Fred Draked86ed291999-12-15 15:34:33 +00009731#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009733#endif
Fred Drakec9680921999-12-13 16:37:25 +00009734#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
Fred Draked86ed291999-12-15 15:34:33 +00009749#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009751#endif
Fred Drakec9680921999-12-13 16:37:25 +00009752#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
Fred Draked86ed291999-12-15 15:34:33 +00009821#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009823#endif
Fred Drakec9680921999-12-13 16:37:25 +00009824#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
Fred Draked86ed291999-12-15 15:34:33 +00009833#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009835#endif
Fred Drakec9680921999-12-13 16:37:25 +00009836#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
Fred Draked86ed291999-12-15 15:34:33 +00009839#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
9842#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009844#endif
Fred Drakec9680921999-12-13 16:37:25 +00009845#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
Fred Draked86ed291999-12-15 15:34:33 +00009857#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009859#endif
Fred Drakec9680921999-12-13 16:37:25 +00009860#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
Fred Draked86ed291999-12-15 15:34:33 +00009881#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009883#endif
Fred Drakec9680921999-12-13 16:37:25 +00009884#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
Fred Draked86ed291999-12-15 15:34:33 +00009890#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009892#endif
Fred Drakec9680921999-12-13 16:37:25 +00009893#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
Fred Draked86ed291999-12-15 15:34:33 +00009920#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009922#endif
9923#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009925#endif
Fred Drakec9680921999-12-13 16:37:25 +00009926#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
Fred Draked86ed291999-12-15 15:34:33 +000010031#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010033#endif
Fred Drakec9680921999-12-13 16:37:25 +000010034#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169};
10170
10171static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010172conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010173{
10174 return conv_confname(arg, valuep, posix_constants_sysconf,
10175 sizeof(posix_constants_sysconf)
10176 / sizeof(struct constdef));
10177}
10178
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010179PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010180"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010181Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010182
10183static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010184posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010185{
10186 PyObject *result = NULL;
10187 int name;
10188
10189 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10190 int value;
10191
10192 errno = 0;
10193 value = sysconf(name);
10194 if (value == -1 && errno != 0)
10195 posix_error();
10196 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010197 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010198 }
10199 return result;
10200}
10201#endif
10202
10203
Fred Drakebec628d1999-12-15 18:31:10 +000010204/* This code is used to ensure that the tables of configuration value names
10205 * are in sorted order as required by conv_confname(), and also to build the
10206 * the exported dictionaries that are used to publish information about the
10207 * names available on the host platform.
10208 *
10209 * Sorting the table at runtime ensures that the table is properly ordered
10210 * when used, even for platforms we're not able to test on. It also makes
10211 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010212 */
Fred Drakebec628d1999-12-15 18:31:10 +000010213
10214static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010215cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010216{
10217 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010219 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010221
10222 return strcmp(c1->name, c2->name);
10223}
10224
10225static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010226setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010228{
Fred Drakebec628d1999-12-15 18:31:10 +000010229 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010230 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010231
10232 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10233 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010234 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010236
Barry Warsaw3155db32000-04-13 15:20:40 +000010237 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 PyObject *o = PyLong_FromLong(table[i].value);
10239 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10240 Py_XDECREF(o);
10241 Py_DECREF(d);
10242 return -1;
10243 }
10244 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010245 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010246 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010247}
10248
Fred Drakebec628d1999-12-15 18:31:10 +000010249/* Return -1 on failure, 0 on success. */
10250static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010251setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010252{
10253#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010254 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010255 sizeof(posix_constants_pathconf)
10256 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010257 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010258 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010259#endif
10260#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010261 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010262 sizeof(posix_constants_confstr)
10263 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010264 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010265 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010266#endif
10267#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010268 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010269 sizeof(posix_constants_sysconf)
10270 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010271 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010272 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010273#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010274 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010275}
Fred Draked86ed291999-12-15 15:34:33 +000010276
10277
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010278PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010279"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010280Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010281in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010282
10283static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010284posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010285{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010286 abort();
10287 /*NOTREACHED*/
10288 Py_FatalError("abort() called from Python code didn't abort!");
10289 return NULL;
10290}
Fred Drakebec628d1999-12-15 18:31:10 +000010291
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010292#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010293PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010294"startfile(filepath [, operation]) - Start a file with its associated\n\
10295application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010296\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010297When \"operation\" is not specified or \"open\", this acts like\n\
10298double-clicking the file in Explorer, or giving the file name as an\n\
10299argument to the DOS \"start\" command: the file is opened with whatever\n\
10300application (if any) its extension is associated.\n\
10301When another \"operation\" is given, it specifies what should be done with\n\
10302the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010303\n\
10304startfile returns as soon as the associated application is launched.\n\
10305There is no option to wait for the application to close, and no way\n\
10306to retrieve the application's exit status.\n\
10307\n\
10308The filepath is relative to the current directory. If you want to use\n\
10309an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010310the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010311
10312static PyObject *
10313win32_startfile(PyObject *self, PyObject *args)
10314{
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 PyObject *ofilepath;
10316 char *filepath;
10317 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010318 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010320
Victor Stinnereb5657a2011-09-30 01:44:27 +020010321 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 if (!PyArg_ParseTuple(args, "U|s:startfile",
10323 &unipath, &operation)) {
10324 PyErr_Clear();
10325 goto normal;
10326 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010327
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010329 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010331 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 PyErr_Clear();
10333 operation = NULL;
10334 goto normal;
10335 }
10336 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010337
Victor Stinnereb5657a2011-09-30 01:44:27 +020010338 wpath = PyUnicode_AsUnicode(unipath);
10339 if (wpath == NULL)
10340 goto normal;
10341 if (uoperation) {
10342 woperation = PyUnicode_AsUnicode(uoperation);
10343 if (woperation == NULL)
10344 goto normal;
10345 }
10346 else
10347 woperation = NULL;
10348
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010350 rc = ShellExecuteW((HWND)0, woperation, wpath,
10351 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 Py_END_ALLOW_THREADS
10353
Victor Stinnereb5657a2011-09-30 01:44:27 +020010354 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010356 win32_error_object("startfile", unipath);
10357 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 }
10359 Py_INCREF(Py_None);
10360 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010361
10362normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10364 PyUnicode_FSConverter, &ofilepath,
10365 &operation))
10366 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010367 if (win32_warn_bytes_api()) {
10368 Py_DECREF(ofilepath);
10369 return NULL;
10370 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 filepath = PyBytes_AsString(ofilepath);
10372 Py_BEGIN_ALLOW_THREADS
10373 rc = ShellExecute((HWND)0, operation, filepath,
10374 NULL, NULL, SW_SHOWNORMAL);
10375 Py_END_ALLOW_THREADS
10376 if (rc <= (HINSTANCE)32) {
10377 PyObject *errval = win32_error("startfile", filepath);
10378 Py_DECREF(ofilepath);
10379 return errval;
10380 }
10381 Py_DECREF(ofilepath);
10382 Py_INCREF(Py_None);
10383 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010384}
10385#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010386
Martin v. Löwis438b5342002-12-27 10:16:42 +000010387#ifdef HAVE_GETLOADAVG
10388PyDoc_STRVAR(posix_getloadavg__doc__,
10389"getloadavg() -> (float, float, float)\n\n\
10390Return the number of processes in the system run queue averaged over\n\
10391the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10392was unobtainable");
10393
10394static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010395posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010396{
10397 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010398 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010399 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10400 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010401 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010402 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010403}
10404#endif
10405
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010406PyDoc_STRVAR(device_encoding__doc__,
10407"device_encoding(fd) -> str\n\n\
10408Return a string describing the encoding of the device\n\
10409if the output is a terminal; else return None.");
10410
10411static PyObject *
10412device_encoding(PyObject *self, PyObject *args)
10413{
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010415
Victor Stinner8c62be82010-05-06 00:08:46 +000010416 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10417 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010418
10419 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010420}
10421
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010422#ifdef HAVE_SETRESUID
10423PyDoc_STRVAR(posix_setresuid__doc__,
10424"setresuid(ruid, euid, suid)\n\n\
10425Set the current process's real, effective, and saved user ids.");
10426
10427static PyObject*
10428posix_setresuid (PyObject *self, PyObject *args)
10429{
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010431 uid_t ruid, euid, suid;
10432 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10433 _Py_Uid_Converter, &ruid,
10434 _Py_Uid_Converter, &euid,
10435 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 return NULL;
10437 if (setresuid(ruid, euid, suid) < 0)
10438 return posix_error();
10439 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010440}
10441#endif
10442
10443#ifdef HAVE_SETRESGID
10444PyDoc_STRVAR(posix_setresgid__doc__,
10445"setresgid(rgid, egid, sgid)\n\n\
10446Set the current process's real, effective, and saved group ids.");
10447
10448static PyObject*
10449posix_setresgid (PyObject *self, PyObject *args)
10450{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010451 gid_t rgid, egid, sgid;
10452 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10453 _Py_Gid_Converter, &rgid,
10454 _Py_Gid_Converter, &egid,
10455 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 return NULL;
10457 if (setresgid(rgid, egid, sgid) < 0)
10458 return posix_error();
10459 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010460}
10461#endif
10462
10463#ifdef HAVE_GETRESUID
10464PyDoc_STRVAR(posix_getresuid__doc__,
10465"getresuid() -> (ruid, euid, suid)\n\n\
10466Get tuple of the current process's real, effective, and saved user ids.");
10467
10468static PyObject*
10469posix_getresuid (PyObject *self, PyObject *noargs)
10470{
Victor Stinner8c62be82010-05-06 00:08:46 +000010471 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 if (getresuid(&ruid, &euid, &suid) < 0)
10473 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010474 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10475 _PyLong_FromUid(euid),
10476 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010477}
10478#endif
10479
10480#ifdef HAVE_GETRESGID
10481PyDoc_STRVAR(posix_getresgid__doc__,
10482"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010483Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010484
10485static PyObject*
10486posix_getresgid (PyObject *self, PyObject *noargs)
10487{
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010489 if (getresgid(&rgid, &egid, &sgid) < 0)
10490 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010491 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10492 _PyLong_FromGid(egid),
10493 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010494}
10495#endif
10496
Benjamin Peterson9428d532011-09-14 11:45:52 -040010497#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010498
Benjamin Peterson799bd802011-08-31 22:15:17 -040010499PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010500"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10501Return the value of extended attribute attribute on path.\n\
10502\n\
10503path may be either a string or an open file descriptor.\n\
10504If follow_symlinks is False, and the last element of the path is a symbolic\n\
10505 link, getxattr will examine the symbolic link itself instead of the file\n\
10506 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010507
10508static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010509posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010510{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010511 path_t path;
10512 path_t attribute;
10513 int follow_symlinks = 1;
10514 PyObject *buffer = NULL;
10515 int i;
10516 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010517
Larry Hastings9cf065c2012-06-22 16:30:09 -070010518 memset(&path, 0, sizeof(path));
10519 memset(&attribute, 0, sizeof(attribute));
10520 path.allow_fd = 1;
10521 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10522 path_converter, &path,
10523 path_converter, &attribute,
10524 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010525 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010526
Larry Hastings9cf065c2012-06-22 16:30:09 -070010527 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10528 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010529
Larry Hastings9cf065c2012-06-22 16:30:09 -070010530 for (i = 0; ; i++) {
10531 void *ptr;
10532 ssize_t result;
10533 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10534 Py_ssize_t buffer_size = buffer_sizes[i];
10535 if (!buffer_size) {
10536 path_error("getxattr", &path);
10537 goto exit;
10538 }
10539 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10540 if (!buffer)
10541 goto exit;
10542 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010543
Larry Hastings9cf065c2012-06-22 16:30:09 -070010544 Py_BEGIN_ALLOW_THREADS;
10545 if (path.fd >= 0)
10546 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10547 else if (follow_symlinks)
10548 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10549 else
10550 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10551 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010552
Larry Hastings9cf065c2012-06-22 16:30:09 -070010553 if (result < 0) {
10554 Py_DECREF(buffer);
10555 buffer = NULL;
10556 if (errno == ERANGE)
10557 continue;
10558 path_error("getxattr", &path);
10559 goto exit;
10560 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561
Larry Hastings9cf065c2012-06-22 16:30:09 -070010562 if (result != buffer_size) {
10563 /* Can only shrink. */
10564 _PyBytes_Resize(&buffer, result);
10565 }
10566 break;
10567 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010568
Larry Hastings9cf065c2012-06-22 16:30:09 -070010569exit:
10570 path_cleanup(&path);
10571 path_cleanup(&attribute);
10572 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010573}
10574
10575PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010576"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10577Set extended attribute attribute on path to value.\n\
10578path may be either a string or an open file descriptor.\n\
10579If follow_symlinks is False, and the last element of the path is a symbolic\n\
10580 link, setxattr will modify the symbolic link itself instead of the file\n\
10581 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010582
10583static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010584posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010585{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010586 path_t path;
10587 path_t attribute;
10588 Py_buffer value;
10589 int flags = 0;
10590 int follow_symlinks = 1;
10591 int result;
10592 PyObject *return_value = NULL;
10593 static char *keywords[] = {"path", "attribute", "value",
10594 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010595
Larry Hastings9cf065c2012-06-22 16:30:09 -070010596 memset(&path, 0, sizeof(path));
10597 path.allow_fd = 1;
10598 memset(&attribute, 0, sizeof(attribute));
10599 memset(&value, 0, sizeof(value));
10600 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10601 keywords,
10602 path_converter, &path,
10603 path_converter, &attribute,
10604 &value, &flags,
10605 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010606 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010607
10608 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10609 goto exit;
10610
Benjamin Peterson799bd802011-08-31 22:15:17 -040010611 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 if (path.fd > -1)
10613 result = fsetxattr(path.fd, attribute.narrow,
10614 value.buf, value.len, flags);
10615 else if (follow_symlinks)
10616 result = setxattr(path.narrow, attribute.narrow,
10617 value.buf, value.len, flags);
10618 else
10619 result = lsetxattr(path.narrow, attribute.narrow,
10620 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010621 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010622
Larry Hastings9cf065c2012-06-22 16:30:09 -070010623 if (result) {
10624 return_value = path_error("setxattr", &path);
10625 goto exit;
10626 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010627
Larry Hastings9cf065c2012-06-22 16:30:09 -070010628 return_value = Py_None;
10629 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010630
Larry Hastings9cf065c2012-06-22 16:30:09 -070010631exit:
10632 path_cleanup(&path);
10633 path_cleanup(&attribute);
10634 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010635
Larry Hastings9cf065c2012-06-22 16:30:09 -070010636 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010637}
10638
10639PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010640"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10641Remove extended attribute attribute on path.\n\
10642path may be either a string or an open file descriptor.\n\
10643If follow_symlinks is False, and the last element of the path is a symbolic\n\
10644 link, removexattr will modify the symbolic link itself instead of the file\n\
10645 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010646
10647static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010648posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010649{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010650 path_t path;
10651 path_t attribute;
10652 int follow_symlinks = 1;
10653 int result;
10654 PyObject *return_value = NULL;
10655 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010656
Larry Hastings9cf065c2012-06-22 16:30:09 -070010657 memset(&path, 0, sizeof(path));
10658 memset(&attribute, 0, sizeof(attribute));
10659 path.allow_fd = 1;
10660 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10661 keywords,
10662 path_converter, &path,
10663 path_converter, &attribute,
10664 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010665 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010666
10667 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10668 goto exit;
10669
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010671 if (path.fd > -1)
10672 result = fremovexattr(path.fd, attribute.narrow);
10673 else if (follow_symlinks)
10674 result = removexattr(path.narrow, attribute.narrow);
10675 else
10676 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010677 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010678
Larry Hastings9cf065c2012-06-22 16:30:09 -070010679 if (result) {
10680 return_value = path_error("removexattr", &path);
10681 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010682 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010683
Larry Hastings9cf065c2012-06-22 16:30:09 -070010684 return_value = Py_None;
10685 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010686
Larry Hastings9cf065c2012-06-22 16:30:09 -070010687exit:
10688 path_cleanup(&path);
10689 path_cleanup(&attribute);
10690
10691 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010692}
10693
10694PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010695"listxattr(path='.', *, follow_symlinks=True)\n\n\
10696Return a list of extended attributes on path.\n\
10697\n\
10698path may be either None, a string, or an open file descriptor.\n\
10699if path is None, listxattr will examine the current directory.\n\
10700If follow_symlinks is False, and the last element of the path is a symbolic\n\
10701 link, listxattr will examine the symbolic link itself instead of the file\n\
10702 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010703
10704static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010705posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010706{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010707 path_t path;
10708 int follow_symlinks = 1;
10709 Py_ssize_t i;
10710 PyObject *result = NULL;
10711 char *buffer = NULL;
10712 char *name;
10713 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010714
Larry Hastings9cf065c2012-06-22 16:30:09 -070010715 memset(&path, 0, sizeof(path));
10716 path.allow_fd = 1;
10717 path.fd = -1;
10718 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10719 path_converter, &path,
10720 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010721 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010722
Larry Hastings9cf065c2012-06-22 16:30:09 -070010723 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10724 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010725
Larry Hastings9cf065c2012-06-22 16:30:09 -070010726 name = path.narrow ? path.narrow : ".";
10727 for (i = 0; ; i++) {
10728 char *start, *trace, *end;
10729 ssize_t length;
10730 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10731 Py_ssize_t buffer_size = buffer_sizes[i];
10732 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010733 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010734 path_error("listxattr", &path);
10735 break;
10736 }
10737 buffer = PyMem_MALLOC(buffer_size);
10738 if (!buffer) {
10739 PyErr_NoMemory();
10740 break;
10741 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010742
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743 Py_BEGIN_ALLOW_THREADS;
10744 if (path.fd > -1)
10745 length = flistxattr(path.fd, buffer, buffer_size);
10746 else if (follow_symlinks)
10747 length = listxattr(name, buffer, buffer_size);
10748 else
10749 length = llistxattr(name, buffer, buffer_size);
10750 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010751
Larry Hastings9cf065c2012-06-22 16:30:09 -070010752 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010753 if (errno == ERANGE) {
10754 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010755 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010756 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010757 }
Larry Hastings9cf065c2012-06-22 16:30:09 -070010758 path_error("listxattr", &path);
10759 break;
10760 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010761
Larry Hastings9cf065c2012-06-22 16:30:09 -070010762 result = PyList_New(0);
10763 if (!result) {
10764 goto exit;
10765 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010766
Larry Hastings9cf065c2012-06-22 16:30:09 -070010767 end = buffer + length;
10768 for (trace = start = buffer; trace != end; trace++) {
10769 if (!*trace) {
10770 int error;
10771 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10772 trace - start);
10773 if (!attribute) {
10774 Py_DECREF(result);
10775 result = NULL;
10776 goto exit;
10777 }
10778 error = PyList_Append(result, attribute);
10779 Py_DECREF(attribute);
10780 if (error) {
10781 Py_DECREF(result);
10782 result = NULL;
10783 goto exit;
10784 }
10785 start = trace + 1;
10786 }
10787 }
10788 break;
10789 }
10790exit:
10791 path_cleanup(&path);
10792 if (buffer)
10793 PyMem_FREE(buffer);
10794 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010795}
10796
Benjamin Peterson9428d532011-09-14 11:45:52 -040010797#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010798
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010799
Georg Brandl2fb477c2012-02-21 00:33:36 +010010800PyDoc_STRVAR(posix_urandom__doc__,
10801"urandom(n) -> str\n\n\
10802Return n random bytes suitable for cryptographic use.");
10803
10804static PyObject *
10805posix_urandom(PyObject *self, PyObject *args)
10806{
10807 Py_ssize_t size;
10808 PyObject *result;
10809 int ret;
10810
10811 /* Read arguments */
10812 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10813 return NULL;
10814 if (size < 0)
10815 return PyErr_Format(PyExc_ValueError,
10816 "negative argument not allowed");
10817 result = PyBytes_FromStringAndSize(NULL, size);
10818 if (result == NULL)
10819 return NULL;
10820
10821 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10822 PyBytes_GET_SIZE(result));
10823 if (ret == -1) {
10824 Py_DECREF(result);
10825 return NULL;
10826 }
10827 return result;
10828}
10829
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010830/* Terminal size querying */
10831
10832static PyTypeObject TerminalSizeType;
10833
10834PyDoc_STRVAR(TerminalSize_docstring,
10835 "A tuple of (columns, lines) for holding terminal window size");
10836
10837static PyStructSequence_Field TerminalSize_fields[] = {
10838 {"columns", "width of the terminal window in characters"},
10839 {"lines", "height of the terminal window in characters"},
10840 {NULL, NULL}
10841};
10842
10843static PyStructSequence_Desc TerminalSize_desc = {
10844 "os.terminal_size",
10845 TerminalSize_docstring,
10846 TerminalSize_fields,
10847 2,
10848};
10849
10850#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10851PyDoc_STRVAR(termsize__doc__,
10852 "Return the size of the terminal window as (columns, lines).\n" \
10853 "\n" \
10854 "The optional argument fd (default standard output) specifies\n" \
10855 "which file descriptor should be queried.\n" \
10856 "\n" \
10857 "If the file descriptor is not connected to a terminal, an OSError\n" \
10858 "is thrown.\n" \
10859 "\n" \
10860 "This function will only be defined if an implementation is\n" \
10861 "available for this system.\n" \
10862 "\n" \
10863 "shutil.get_terminal_size is the high-level function which should \n" \
10864 "normally be used, os.get_terminal_size is the low-level implementation.");
10865
10866static PyObject*
10867get_terminal_size(PyObject *self, PyObject *args)
10868{
10869 int columns, lines;
10870 PyObject *termsize;
10871
10872 int fd = fileno(stdout);
10873 /* Under some conditions stdout may not be connected and
10874 * fileno(stdout) may point to an invalid file descriptor. For example
10875 * GUI apps don't have valid standard streams by default.
10876 *
10877 * If this happens, and the optional fd argument is not present,
10878 * the ioctl below will fail returning EBADF. This is what we want.
10879 */
10880
10881 if (!PyArg_ParseTuple(args, "|i", &fd))
10882 return NULL;
10883
10884#ifdef TERMSIZE_USE_IOCTL
10885 {
10886 struct winsize w;
10887 if (ioctl(fd, TIOCGWINSZ, &w))
10888 return PyErr_SetFromErrno(PyExc_OSError);
10889 columns = w.ws_col;
10890 lines = w.ws_row;
10891 }
10892#endif /* TERMSIZE_USE_IOCTL */
10893
10894#ifdef TERMSIZE_USE_CONIO
10895 {
10896 DWORD nhandle;
10897 HANDLE handle;
10898 CONSOLE_SCREEN_BUFFER_INFO csbi;
10899 switch (fd) {
10900 case 0: nhandle = STD_INPUT_HANDLE;
10901 break;
10902 case 1: nhandle = STD_OUTPUT_HANDLE;
10903 break;
10904 case 2: nhandle = STD_ERROR_HANDLE;
10905 break;
10906 default:
10907 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10908 }
10909 handle = GetStdHandle(nhandle);
10910 if (handle == NULL)
10911 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10912 if (handle == INVALID_HANDLE_VALUE)
10913 return PyErr_SetFromWindowsErr(0);
10914
10915 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10916 return PyErr_SetFromWindowsErr(0);
10917
10918 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10919 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10920 }
10921#endif /* TERMSIZE_USE_CONIO */
10922
10923 termsize = PyStructSequence_New(&TerminalSizeType);
10924 if (termsize == NULL)
10925 return NULL;
10926 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10927 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10928 if (PyErr_Occurred()) {
10929 Py_DECREF(termsize);
10930 return NULL;
10931 }
10932 return termsize;
10933}
10934#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10935
10936
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010937static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010938 {"access", (PyCFunction)posix_access,
10939 METH_VARARGS | METH_KEYWORDS,
10940 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010941#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010943#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010944 {"chdir", (PyCFunction)posix_chdir,
10945 METH_VARARGS | METH_KEYWORDS,
10946 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010947#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010948 {"chflags", (PyCFunction)posix_chflags,
10949 METH_VARARGS | METH_KEYWORDS,
10950 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010951#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010952 {"chmod", (PyCFunction)posix_chmod,
10953 METH_VARARGS | METH_KEYWORDS,
10954 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010955#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010957#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010958#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010959 {"chown", (PyCFunction)posix_chown,
10960 METH_VARARGS | METH_KEYWORDS,
10961 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010962#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010963#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010964 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010965#endif /* HAVE_LCHMOD */
10966#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010967 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010968#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010969#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010971#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010972#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010974#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010975#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010977#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010978#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010980#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010981#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10983 METH_NOARGS, posix_getcwd__doc__},
10984 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10985 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010986#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010987#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10988 {"link", (PyCFunction)posix_link,
10989 METH_VARARGS | METH_KEYWORDS,
10990 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010991#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010992 {"listdir", (PyCFunction)posix_listdir,
10993 METH_VARARGS | METH_KEYWORDS,
10994 posix_listdir__doc__},
10995 {"lstat", (PyCFunction)posix_lstat,
10996 METH_VARARGS | METH_KEYWORDS,
10997 posix_lstat__doc__},
10998 {"mkdir", (PyCFunction)posix_mkdir,
10999 METH_VARARGS | METH_KEYWORDS,
11000 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011001#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011002 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011003#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011004#ifdef HAVE_GETPRIORITY
11005 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11006#endif /* HAVE_GETPRIORITY */
11007#ifdef HAVE_SETPRIORITY
11008 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11009#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011010#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 {"readlink", (PyCFunction)posix_readlink,
11012 METH_VARARGS | METH_KEYWORDS,
11013 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011014#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011015#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011016 {"readlink", (PyCFunction)win_readlink,
11017 METH_VARARGS | METH_KEYWORDS,
11018 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011019#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 {"rename", (PyCFunction)posix_rename,
11021 METH_VARARGS | METH_KEYWORDS,
11022 posix_rename__doc__},
11023 {"replace", (PyCFunction)posix_replace,
11024 METH_VARARGS | METH_KEYWORDS,
11025 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011026 {"rmdir", (PyCFunction)posix_rmdir,
11027 METH_VARARGS | METH_KEYWORDS,
11028 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011029 {"stat", (PyCFunction)posix_stat,
11030 METH_VARARGS | METH_KEYWORDS,
11031 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011033#if defined(HAVE_SYMLINK)
11034 {"symlink", (PyCFunction)posix_symlink,
11035 METH_VARARGS | METH_KEYWORDS,
11036 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011037#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011038#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011039 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011040#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011042#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011043 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011044#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011045 {"unlink", (PyCFunction)posix_unlink,
11046 METH_VARARGS | METH_KEYWORDS,
11047 posix_unlink__doc__},
11048 {"remove", (PyCFunction)posix_unlink,
11049 METH_VARARGS | METH_KEYWORDS,
11050 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011051 {"utime", (PyCFunction)posix_utime,
11052 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011053#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011054 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011055#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011057#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011058 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011059 {"execve", (PyCFunction)posix_execve,
11060 METH_VARARGS | METH_KEYWORDS,
11061 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011062#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011063#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011064 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11065 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000011066#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011067 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
11068 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000011069#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000011070#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011071#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011073#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011074#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011076#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011077#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011078#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011079 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11080 {"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 +020011081#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011082#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011083 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011084#endif
11085#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011086 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011087#endif
11088#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011089 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011090#endif
11091#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011092 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011093#endif
11094#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011095 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011096#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011097 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011098#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011099 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11100 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11101#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011102#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011103#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011105#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011106#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011108#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011109#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011111#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011112#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011114#endif /* HAVE_GETEUID */
11115#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011117#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011118#ifdef HAVE_GETGROUPLIST
11119 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11120#endif
Fred Drakec9680921999-12-13 16:37:25 +000011121#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011123#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011125#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011126 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011127#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011128#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011129 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011130#endif /* HAVE_GETPPID */
11131#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011132 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011133#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011134#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011135 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011136#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011137#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011138 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011139#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011140#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011141 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011142#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011143#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011145#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011146#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11148 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011149#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011150#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011152#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011153#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011155#endif /* HAVE_SETEUID */
11156#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011158#endif /* HAVE_SETEGID */
11159#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011161#endif /* HAVE_SETREUID */
11162#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011164#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011165#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011167#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011168#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011170#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011171#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011173#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011174#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011176#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011177#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011178 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011179#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011180#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011181 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011182#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011183#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011184 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011185#endif /* HAVE_WAIT3 */
11186#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011187 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011188#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011189#if defined(HAVE_WAITID) && !defined(__APPLE__)
11190 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11191#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011192#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011193 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011194#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011195#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011196 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011197#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011198#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011200#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011201#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011203#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011204#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011206#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011207#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011209#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011210 {"open", (PyCFunction)posix_open,\
11211 METH_VARARGS | METH_KEYWORDS,
11212 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011213 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11214 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11215 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11216 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11217 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011218#ifdef HAVE_LOCKF
11219 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11220#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11222 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011223#ifdef HAVE_READV
11224 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11225#endif
11226#ifdef HAVE_PREAD
11227 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11228#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011230#ifdef HAVE_WRITEV
11231 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11232#endif
11233#ifdef HAVE_PWRITE
11234 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11235#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011236#ifdef HAVE_SENDFILE
11237 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11238 posix_sendfile__doc__},
11239#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011240 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011242#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011244#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011245#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011246 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011247#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011248#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011249 {"mkfifo", (PyCFunction)posix_mkfifo,
11250 METH_VARARGS | METH_KEYWORDS,
11251 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011252#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011253#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011254 {"mknod", (PyCFunction)posix_mknod,
11255 METH_VARARGS | METH_KEYWORDS,
11256 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011257#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011258#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11260 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11261 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011262#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011263#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011264 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011265#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011266#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011267 {"truncate", (PyCFunction)posix_truncate,
11268 METH_VARARGS | METH_KEYWORDS,
11269 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011270#endif
11271#ifdef HAVE_POSIX_FALLOCATE
11272 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11273#endif
11274#ifdef HAVE_POSIX_FADVISE
11275 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11276#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011277#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011278 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011279#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011280#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011281 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011282#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011284#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011286#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011287#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011288 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011289#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011290#ifdef HAVE_SYNC
11291 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11292#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011293#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011295#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011296#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011297#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011299#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011300#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011302#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011303#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011305#endif /* WIFSTOPPED */
11306#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011308#endif /* WIFSIGNALED */
11309#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011311#endif /* WIFEXITED */
11312#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011314#endif /* WEXITSTATUS */
11315#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011317#endif /* WTERMSIG */
11318#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011320#endif /* WSTOPSIG */
11321#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011322#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011323 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011324#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011325#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011326 {"statvfs", (PyCFunction)posix_statvfs,
11327 METH_VARARGS | METH_KEYWORDS,
11328 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011329#endif
Fred Drakec9680921999-12-13 16:37:25 +000011330#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011332#endif
11333#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011334 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011335#endif
11336#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011337 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011338#endif
11339#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011340 {"pathconf", (PyCFunction)posix_pathconf,
11341 METH_VARARGS | METH_KEYWORDS,
11342 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011343#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011344 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011345#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011347 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011348 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011349 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011350 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011351#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011352#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011353 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011354#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011355 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011356#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011358#endif
11359#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011361#endif
11362#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011364#endif
11365#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011367#endif
11368
Benjamin Peterson9428d532011-09-14 11:45:52 -040011369#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011370 {"setxattr", (PyCFunction)posix_setxattr,
11371 METH_VARARGS | METH_KEYWORDS,
11372 posix_setxattr__doc__},
11373 {"getxattr", (PyCFunction)posix_getxattr,
11374 METH_VARARGS | METH_KEYWORDS,
11375 posix_getxattr__doc__},
11376 {"removexattr", (PyCFunction)posix_removexattr,
11377 METH_VARARGS | METH_KEYWORDS,
11378 posix_removexattr__doc__},
11379 {"listxattr", (PyCFunction)posix_listxattr,
11380 METH_VARARGS | METH_KEYWORDS,
11381 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011382#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011383#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11384 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11385#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011386 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011387};
11388
11389
Barry Warsaw4a342091996-12-19 23:50:02 +000011390static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011391ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011392{
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011394}
11395
Guido van Rossumd48f2521997-12-05 22:19:34 +000011396#if defined(PYOS_OS2)
11397/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011398static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011399{
11400 APIRET rc;
11401 ULONG values[QSV_MAX+1];
11402 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011403 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011404
11405 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011406 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011407 Py_END_ALLOW_THREADS
11408
11409 if (rc != NO_ERROR) {
11410 os2_error(rc);
11411 return -1;
11412 }
11413
Fred Drake4d1e64b2002-04-15 19:40:07 +000011414 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11415 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11416 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11417 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11418 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11419 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11420 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011421
11422 switch (values[QSV_VERSION_MINOR]) {
11423 case 0: ver = "2.00"; break;
11424 case 10: ver = "2.10"; break;
11425 case 11: ver = "2.11"; break;
11426 case 30: ver = "3.00"; break;
11427 case 40: ver = "4.00"; break;
11428 case 50: ver = "5.00"; break;
11429 default:
Tim Peters885d4572001-11-28 20:27:42 +000011430 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011431 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011432 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011433 ver = &tmp[0];
11434 }
11435
11436 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011437 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011438 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011439
11440 /* Add Indicator of Which Drive was Used to Boot the System */
11441 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11442 tmp[1] = ':';
11443 tmp[2] = '\0';
11444
Fred Drake4d1e64b2002-04-15 19:40:07 +000011445 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011446}
11447#endif
11448
Brian Curtin52173d42010-12-02 18:29:18 +000011449#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011450static int
Brian Curtin52173d42010-12-02 18:29:18 +000011451enable_symlink()
11452{
11453 HANDLE tok;
11454 TOKEN_PRIVILEGES tok_priv;
11455 LUID luid;
11456 int meth_idx = 0;
11457
11458 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011459 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011460
11461 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011462 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011463
11464 tok_priv.PrivilegeCount = 1;
11465 tok_priv.Privileges[0].Luid = luid;
11466 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11467
11468 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11469 sizeof(TOKEN_PRIVILEGES),
11470 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011471 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011472
Brian Curtin3b4499c2010-12-28 14:31:47 +000011473 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11474 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011475}
11476#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11477
Barry Warsaw4a342091996-12-19 23:50:02 +000011478static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011479all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011480{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011481#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011482 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011483#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011484#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011485 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011486#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011487#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011488 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011489#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011490#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011492#endif
Fred Drakec9680921999-12-13 16:37:25 +000011493#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011495#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011496#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011497 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011498#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011499#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011500 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011501#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011502#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011504#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011505#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011506 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011507#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011508#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011509 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011510#endif
11511#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011512 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011513#endif
11514#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011515 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011516#endif
11517#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011518 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011519#endif
11520#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011521 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011522#endif
11523#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011524 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011525#endif
11526#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011527 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011528#endif
11529#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011531#endif
11532#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011533 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011534#endif
11535#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011536 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011537#endif
11538#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011540#endif
11541#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011542 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011543#endif
11544#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011545 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011546#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011547#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011549#endif
11550#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011552#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011553#ifdef O_XATTR
11554 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11555#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011556#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011557 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011558#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011559#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011560 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011561#endif
11562#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011563 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011564#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011565#ifdef O_EXEC
11566 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11567#endif
11568#ifdef O_SEARCH
11569 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11570#endif
11571#ifdef O_TTY_INIT
11572 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11573#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011574#ifdef PRIO_PROCESS
11575 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11576#endif
11577#ifdef PRIO_PGRP
11578 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11579#endif
11580#ifdef PRIO_USER
11581 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11582#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011583#ifdef O_CLOEXEC
11584 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11585#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011586#ifdef O_ACCMODE
11587 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11588#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011589
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011590
Jesus Cea94363612012-06-22 18:32:07 +020011591#ifdef SEEK_HOLE
11592 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11593#endif
11594#ifdef SEEK_DATA
11595 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11596#endif
11597
Tim Peters5aa91602002-01-30 05:46:57 +000011598/* MS Windows */
11599#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 /* Don't inherit in child processes. */
11601 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011602#endif
11603#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011604 /* Optimize for short life (keep in memory). */
11605 /* MS forgot to define this one with a non-underscore form too. */
11606 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011607#endif
11608#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011609 /* Automatically delete when last handle is closed. */
11610 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011611#endif
11612#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 /* Optimize for random access. */
11614 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011615#endif
11616#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011617 /* Optimize for sequential access. */
11618 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011619#endif
11620
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011621/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011622#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011623 /* Send a SIGIO signal whenever input or output
11624 becomes available on file descriptor */
11625 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011626#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011627#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011628 /* Direct disk access. */
11629 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011630#endif
11631#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011632 /* Must be a directory. */
11633 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011634#endif
11635#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011636 /* Do not follow links. */
11637 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011638#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011639#ifdef O_NOLINKS
11640 /* Fails if link count of the named file is greater than 1 */
11641 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11642#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011643#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011644 /* Do not update the access time. */
11645 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011646#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011647
Victor Stinner8c62be82010-05-06 00:08:46 +000011648 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011649#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011650 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011651#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011652#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011653 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011654#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011655#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011656 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011657#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011658#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011659 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011660#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011661#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011662 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011663#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011664#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011665 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011666#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011667#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011668 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011669#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011670#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011671 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011672#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011673#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011674 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011675#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011676#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011677 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011678#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011679#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011680 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011681#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011682#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011683 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011684#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011685#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011686 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011687#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011688#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011689 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011690#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011691#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011692 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011693#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011694#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011695 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011696#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011697#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011698 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011699#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011700
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011701 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011702#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011703 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011704#endif /* ST_RDONLY */
11705#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011706 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011707#endif /* ST_NOSUID */
11708
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011709 /* FreeBSD sendfile() constants */
11710#ifdef SF_NODISKIO
11711 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11712#endif
11713#ifdef SF_MNOWAIT
11714 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11715#endif
11716#ifdef SF_SYNC
11717 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11718#endif
11719
Ross Lagerwall7807c352011-03-17 20:20:30 +020011720 /* constants for posix_fadvise */
11721#ifdef POSIX_FADV_NORMAL
11722 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11723#endif
11724#ifdef POSIX_FADV_SEQUENTIAL
11725 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11726#endif
11727#ifdef POSIX_FADV_RANDOM
11728 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11729#endif
11730#ifdef POSIX_FADV_NOREUSE
11731 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11732#endif
11733#ifdef POSIX_FADV_WILLNEED
11734 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11735#endif
11736#ifdef POSIX_FADV_DONTNEED
11737 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11738#endif
11739
11740 /* constants for waitid */
11741#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11742 if (ins(d, "P_PID", (long)P_PID)) return -1;
11743 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11744 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11745#endif
11746#ifdef WEXITED
11747 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11748#endif
11749#ifdef WNOWAIT
11750 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11751#endif
11752#ifdef WSTOPPED
11753 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11754#endif
11755#ifdef CLD_EXITED
11756 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11757#endif
11758#ifdef CLD_DUMPED
11759 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11760#endif
11761#ifdef CLD_TRAPPED
11762 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11763#endif
11764#ifdef CLD_CONTINUED
11765 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11766#endif
11767
11768 /* constants for lockf */
11769#ifdef F_LOCK
11770 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11771#endif
11772#ifdef F_TLOCK
11773 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11774#endif
11775#ifdef F_ULOCK
11776 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11777#endif
11778#ifdef F_TEST
11779 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11780#endif
11781
Guido van Rossum246bc171999-02-01 23:54:31 +000011782#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011783#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011784 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11785 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11786 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11787 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11788 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11789 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11790 if (ins(d, "P_PM", (long)P_PM)) return -1;
11791 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11792 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11793 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11794 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11795 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11796 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11797 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11798 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11799 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11800 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11801 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11802 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11803 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011804#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011805 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11806 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11807 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11808 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11809 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011810#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011811#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011812
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011813#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011814 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011815 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11816 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11817#ifdef SCHED_SPORADIC
11818 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11819#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011820#ifdef SCHED_BATCH
11821 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11822#endif
11823#ifdef SCHED_IDLE
11824 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11825#endif
11826#ifdef SCHED_RESET_ON_FORK
11827 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11828#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011829#ifdef SCHED_SYS
11830 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11831#endif
11832#ifdef SCHED_IA
11833 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11834#endif
11835#ifdef SCHED_FSS
11836 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11837#endif
11838#ifdef SCHED_FX
11839 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11840#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011841#endif
11842
Benjamin Peterson9428d532011-09-14 11:45:52 -040011843#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011844 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11845 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11846 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11847#endif
11848
Victor Stinner8b905bd2011-10-25 13:34:04 +020011849#ifdef RTLD_LAZY
11850 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11851#endif
11852#ifdef RTLD_NOW
11853 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11854#endif
11855#ifdef RTLD_GLOBAL
11856 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11857#endif
11858#ifdef RTLD_LOCAL
11859 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11860#endif
11861#ifdef RTLD_NODELETE
11862 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11863#endif
11864#ifdef RTLD_NOLOAD
11865 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11866#endif
11867#ifdef RTLD_DEEPBIND
11868 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11869#endif
11870
Guido van Rossumd48f2521997-12-05 22:19:34 +000011871#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011872 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011873#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011874 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011875}
11876
11877
Tim Peters5aa91602002-01-30 05:46:57 +000011878#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011879#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011880#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011881
11882#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011883#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011884#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011885
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011886#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011887#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011888#define MODNAME "posix"
11889#endif
11890
Martin v. Löwis1a214512008-06-11 05:26:20 +000011891static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011892 PyModuleDef_HEAD_INIT,
11893 MODNAME,
11894 posix__doc__,
11895 -1,
11896 posix_methods,
11897 NULL,
11898 NULL,
11899 NULL,
11900 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011901};
11902
11903
Larry Hastings9cf065c2012-06-22 16:30:09 -070011904static char *have_functions[] = {
11905
11906#ifdef HAVE_FACCESSAT
11907 "HAVE_FACCESSAT",
11908#endif
11909
11910#ifdef HAVE_FCHDIR
11911 "HAVE_FCHDIR",
11912#endif
11913
11914#ifdef HAVE_FCHMOD
11915 "HAVE_FCHMOD",
11916#endif
11917
11918#ifdef HAVE_FCHMODAT
11919 "HAVE_FCHMODAT",
11920#endif
11921
11922#ifdef HAVE_FCHOWN
11923 "HAVE_FCHOWN",
11924#endif
11925
11926#ifdef HAVE_FEXECVE
11927 "HAVE_FEXECVE",
11928#endif
11929
11930#ifdef HAVE_FDOPENDIR
11931 "HAVE_FDOPENDIR",
11932#endif
11933
Georg Brandl306336b2012-06-24 12:55:33 +020011934#ifdef HAVE_FPATHCONF
11935 "HAVE_FPATHCONF",
11936#endif
11937
Larry Hastings9cf065c2012-06-22 16:30:09 -070011938#ifdef HAVE_FSTATAT
11939 "HAVE_FSTATAT",
11940#endif
11941
11942#ifdef HAVE_FSTATVFS
11943 "HAVE_FSTATVFS",
11944#endif
11945
Georg Brandl306336b2012-06-24 12:55:33 +020011946#ifdef HAVE_FTRUNCATE
11947 "HAVE_FTRUNCATE",
11948#endif
11949
Larry Hastings9cf065c2012-06-22 16:30:09 -070011950#ifdef HAVE_FUTIMENS
11951 "HAVE_FUTIMENS",
11952#endif
11953
11954#ifdef HAVE_FUTIMES
11955 "HAVE_FUTIMES",
11956#endif
11957
11958#ifdef HAVE_FUTIMESAT
11959 "HAVE_FUTIMESAT",
11960#endif
11961
11962#ifdef HAVE_LINKAT
11963 "HAVE_LINKAT",
11964#endif
11965
11966#ifdef HAVE_LCHFLAGS
11967 "HAVE_LCHFLAGS",
11968#endif
11969
11970#ifdef HAVE_LCHMOD
11971 "HAVE_LCHMOD",
11972#endif
11973
11974#ifdef HAVE_LCHOWN
11975 "HAVE_LCHOWN",
11976#endif
11977
11978#ifdef HAVE_LSTAT
11979 "HAVE_LSTAT",
11980#endif
11981
11982#ifdef HAVE_LUTIMES
11983 "HAVE_LUTIMES",
11984#endif
11985
11986#ifdef HAVE_MKDIRAT
11987 "HAVE_MKDIRAT",
11988#endif
11989
11990#ifdef HAVE_MKFIFOAT
11991 "HAVE_MKFIFOAT",
11992#endif
11993
11994#ifdef HAVE_MKNODAT
11995 "HAVE_MKNODAT",
11996#endif
11997
11998#ifdef HAVE_OPENAT
11999 "HAVE_OPENAT",
12000#endif
12001
12002#ifdef HAVE_READLINKAT
12003 "HAVE_READLINKAT",
12004#endif
12005
12006#ifdef HAVE_RENAMEAT
12007 "HAVE_RENAMEAT",
12008#endif
12009
12010#ifdef HAVE_SYMLINKAT
12011 "HAVE_SYMLINKAT",
12012#endif
12013
12014#ifdef HAVE_UNLINKAT
12015 "HAVE_UNLINKAT",
12016#endif
12017
12018#ifdef HAVE_UTIMENSAT
12019 "HAVE_UTIMENSAT",
12020#endif
12021
12022#ifdef MS_WINDOWS
12023 "MS_WINDOWS",
12024#endif
12025
12026 NULL
12027};
12028
12029
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012030PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012031INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012032{
Victor Stinner8c62be82010-05-06 00:08:46 +000012033 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012034 PyObject *list;
12035 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012036
Brian Curtin52173d42010-12-02 18:29:18 +000012037#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012038 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012039#endif
12040
Victor Stinner8c62be82010-05-06 00:08:46 +000012041 m = PyModule_Create(&posixmodule);
12042 if (m == NULL)
12043 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012044
Victor Stinner8c62be82010-05-06 00:08:46 +000012045 /* Initialize environ dictionary */
12046 v = convertenviron();
12047 Py_XINCREF(v);
12048 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12049 return NULL;
12050 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012051
Victor Stinner8c62be82010-05-06 00:08:46 +000012052 if (all_ins(m))
12053 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012054
Victor Stinner8c62be82010-05-06 00:08:46 +000012055 if (setup_confname_tables(m))
12056 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012057
Victor Stinner8c62be82010-05-06 00:08:46 +000012058 Py_INCREF(PyExc_OSError);
12059 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012060
Guido van Rossumb3d39562000-01-31 18:41:26 +000012061#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012062 if (posix_putenv_garbage == NULL)
12063 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012064#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012065
Victor Stinner8c62be82010-05-06 00:08:46 +000012066 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012067#if defined(HAVE_WAITID) && !defined(__APPLE__)
12068 waitid_result_desc.name = MODNAME ".waitid_result";
12069 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
12070#endif
12071
Victor Stinner8c62be82010-05-06 00:08:46 +000012072 stat_result_desc.name = MODNAME ".stat_result";
12073 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12074 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12075 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
12076 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
12077 structseq_new = StatResultType.tp_new;
12078 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012079
Victor Stinner8c62be82010-05-06 00:08:46 +000012080 statvfs_result_desc.name = MODNAME ".statvfs_result";
12081 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012082#ifdef NEED_TICKS_PER_SECOND
12083# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012084 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012085# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012086 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012087# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012088 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012089# endif
12090#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012091
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012092#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012093 sched_param_desc.name = MODNAME ".sched_param";
12094 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
12095 SchedParamType.tp_new = sched_param_new;
12096#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012097
12098 /* initialize TerminalSize_info */
12099 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000012100 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012101#if defined(HAVE_WAITID) && !defined(__APPLE__)
12102 Py_INCREF((PyObject*) &WaitidResultType);
12103 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12104#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012105 Py_INCREF((PyObject*) &StatResultType);
12106 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12107 Py_INCREF((PyObject*) &StatVFSResultType);
12108 PyModule_AddObject(m, "statvfs_result",
12109 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012110
12111#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012112 Py_INCREF(&SchedParamType);
12113 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012114#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012115
Larry Hastings605a62d2012-06-24 04:33:36 -070012116 times_result_desc.name = MODNAME ".times_result";
12117 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
12118 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12119
12120 uname_result_desc.name = MODNAME ".uname_result";
12121 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
12122 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12123
Thomas Wouters477c8d52006-05-27 19:21:47 +000012124#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012125 /*
12126 * Step 2 of weak-linking support on Mac OS X.
12127 *
12128 * The code below removes functions that are not available on the
12129 * currently active platform.
12130 *
12131 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012132 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012133 * OSX 10.4.
12134 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012135#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012136 if (fstatvfs == NULL) {
12137 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12138 return NULL;
12139 }
12140 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012141#endif /* HAVE_FSTATVFS */
12142
12143#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012144 if (statvfs == NULL) {
12145 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12146 return NULL;
12147 }
12148 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012149#endif /* HAVE_STATVFS */
12150
12151# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012152 if (lchown == NULL) {
12153 if (PyObject_DelAttrString(m, "lchown") == -1) {
12154 return NULL;
12155 }
12156 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012157#endif /* HAVE_LCHOWN */
12158
12159
12160#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012161
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012162 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012163 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12164
Larry Hastings6fe20b32012-04-19 15:07:49 -070012165 billion = PyLong_FromLong(1000000000);
12166 if (!billion)
12167 return NULL;
12168
Larry Hastings9cf065c2012-06-22 16:30:09 -070012169 /* suppress "function not used" warnings */
12170 {
12171 int ignored;
12172 fd_specified("", -1);
12173 follow_symlinks_specified("", 1);
12174 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12175 dir_fd_converter(Py_None, &ignored);
12176 dir_fd_unavailable(Py_None, &ignored);
12177 }
12178
12179 /*
12180 * provide list of locally available functions
12181 * so os.py can populate support_* lists
12182 */
12183 list = PyList_New(0);
12184 if (!list)
12185 return NULL;
12186 for (trace = have_functions; *trace; trace++) {
12187 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12188 if (!unicode)
12189 return NULL;
12190 if (PyList_Append(list, unicode))
12191 return NULL;
12192 Py_DECREF(unicode);
12193 }
12194 PyModule_AddObject(m, "_have_functions", list);
12195
12196 initialized = 1;
12197
Victor Stinner8c62be82010-05-06 00:08:46 +000012198 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012199
Guido van Rossumb6775db1994-08-01 11:34:53 +000012200}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012201
12202#ifdef __cplusplus
12203}
12204#endif