blob: 905b1de4ea385f80f92385fa41dd74662959d46a [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
R David Murrayfc069992013-12-13 20:52:19 -05001745 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001746 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
R David Murrayfc069992013-12-13 20:52:19 -05001841 the symlink path again 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;
Victor Stinner45e90392013-07-18 23:57:35 +02002964 PyObject *return_value = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002965 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};
Larry Hastings2e3e5932013-08-01 19:34:46 -07003446#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447 int fd = -1;
Larry Hastings2e3e5932013-08-01 19:34:46 -07003448#endif /* HAVE_FDOPENDIR */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449
3450#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3451 PyObject *v;
3452 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3453 BOOL result;
3454 WIN32_FIND_DATA FileData;
3455 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3456 char *bufptr = namebuf;
3457 /* only claim to have space for MAX_PATH */
3458 Py_ssize_t len = sizeof(namebuf)-5;
3459 PyObject *po = NULL;
3460 wchar_t *wnamebuf = NULL;
3461#elif defined(PYOS_OS2)
3462#ifndef MAX_PATH
3463#define MAX_PATH CCHMAXPATH
3464#endif
3465 char *pt;
3466 PyObject *v;
3467 char namebuf[MAX_PATH+5];
3468 HDIR hdir = 1;
3469 ULONG srchcnt = 1;
3470 FILEFINDBUF3 ep;
3471 APIRET rc;
3472#else
3473 PyObject *v;
3474 DIR *dirp = NULL;
3475 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003476 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477#endif
3478
3479 memset(&path, 0, sizeof(path));
3480 path.nullable = 1;
3481#ifdef HAVE_FDOPENDIR
3482 path.allow_fd = 1;
3483 path.fd = -1;
3484#endif
3485 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3486 path_converter, &path
3487 ))
3488 return NULL;
3489
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 /* XXX Should redo this putting the (now four) versions of opendir
3491 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003492#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003494 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003496
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003498 po_wchars = L".";
3499 len = 1;
3500 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 po_wchars = path.wide;
3502 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003503 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003504 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003505 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3506 if (!wnamebuf) {
3507 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003510 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003512 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 if (wch != L'/' && wch != L'\\' && wch != L':')
3514 wnamebuf[len++] = L'\\';
3515 wcscpy(wnamebuf + len, L"*.*");
3516 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003517 if ((list = PyList_New(0)) == NULL) {
3518 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003520 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003522 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 if (hFindFile == INVALID_HANDLE_VALUE) {
3524 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 if (error == ERROR_FILE_NOT_FOUND)
3526 goto exit;
3527 Py_DECREF(list);
3528 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003531 }
3532 do {
3533 /* Skip over . and .. */
3534 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3535 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 v = PyUnicode_FromWideChar(wFileData.cFileName,
3537 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 Py_DECREF(list);
3540 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 break;
3542 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003545 Py_DECREF(list);
3546 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 break;
3548 }
3549 Py_DECREF(v);
3550 }
3551 Py_BEGIN_ALLOW_THREADS
3552 result = FindNextFileW(hFindFile, &wFileData);
3553 Py_END_ALLOW_THREADS
3554 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3555 it got to the end of the directory. */
3556 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 Py_DECREF(list);
3558 list = win32_error_unicode("FindNextFileW", wnamebuf);
3559 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 }
3561 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003562
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003564 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 strcpy(namebuf, path.narrow);
3566 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 if (len > 0) {
3568 char ch = namebuf[len-1];
3569 if (ch != SEP && ch != ALTSEP && ch != ':')
3570 namebuf[len++] = '/';
3571 strcpy(namebuf + len, "*.*");
3572 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003573
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003576
Antoine Pitroub73caab2010-08-09 23:39:31 +00003577 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003579 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003580 if (hFindFile == INVALID_HANDLE_VALUE) {
3581 int error = GetLastError();
3582 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583 goto exit;
3584 Py_DECREF(list);
3585 list = win32_error("FindFirstFile", namebuf);
3586 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 }
3588 do {
3589 /* Skip over . and .. */
3590 if (strcmp(FileData.cFileName, ".") != 0 &&
3591 strcmp(FileData.cFileName, "..") != 0) {
3592 v = PyBytes_FromString(FileData.cFileName);
3593 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 Py_DECREF(list);
3595 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 break;
3597 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 Py_DECREF(list);
3601 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003602 break;
3603 }
3604 Py_DECREF(v);
3605 }
3606 Py_BEGIN_ALLOW_THREADS
3607 result = FindNextFile(hFindFile, &FileData);
3608 Py_END_ALLOW_THREADS
3609 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3610 it got to the end of the directory. */
3611 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612 Py_DECREF(list);
3613 list = win32_error("FindNextFile", namebuf);
3614 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003615 }
3616 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003617
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618exit:
3619 if (hFindFile != INVALID_HANDLE_VALUE) {
3620 if (FindClose(hFindFile) == FALSE) {
3621 if (list != NULL) {
3622 Py_DECREF(list);
3623 list = win32_error_object("FindClose", path.object);
3624 }
3625 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003626 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627 if (wnamebuf)
3628 free(wnamebuf);
3629 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003630
Larry Hastings9cf065c2012-06-22 16:30:09 -07003631 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003632
Tim Peters0bb44a42000-09-15 07:44:49 +00003633#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003635 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003637 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003639 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003640 if (*pt == ALTSEP)
3641 *pt = SEP;
3642 if (namebuf[len-1] != SEP)
3643 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003644 strcpy(namebuf + len, "*.*");
3645
Larry Hastings9cf065c2012-06-22 16:30:09 -07003646 if ((list = PyList_New(0)) == NULL) {
3647 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003648 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003649
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003650 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3651 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003652 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003653 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3654 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3655 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003656
3657 if (rc != NO_ERROR) {
3658 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659 Py_DECREF(list);
3660 list = posix_error_with_filename(path.narrow);
3661 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003662 }
3663
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003664 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003665 do {
3666 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003667 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003668 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003669
3670 strcpy(namebuf, ep.achName);
3671
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003672 /* Leave Case of Name Alone -- In Native Form */
3673 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003674
Christian Heimes72b710a2008-05-26 13:28:38 +00003675 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003676 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677 Py_DECREF(list);
3678 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003679 break;
3680 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003682 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 Py_DECREF(list);
3684 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003685 break;
3686 }
3687 Py_DECREF(v);
3688 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3689 }
3690
Larry Hastings9cf065c2012-06-22 16:30:09 -07003691exit:
3692 path_cleanup(&path);
3693
3694 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003695#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003696
Victor Stinner8c62be82010-05-06 00:08:46 +00003697 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698#ifdef HAVE_FDOPENDIR
3699 if (path.fd != -1) {
3700 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003701 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003702 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003703 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003704
3705 if (fd == -1) {
3706 list = posix_error();
3707 goto exit;
3708 }
3709
Larry Hastingsfdaea062012-06-25 04:42:23 -07003710 return_str = 1;
3711
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 Py_BEGIN_ALLOW_THREADS
3713 dirp = fdopendir(fd);
3714 Py_END_ALLOW_THREADS
3715 }
3716 else
3717#endif
3718 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003719 char *name;
3720 if (path.narrow) {
3721 name = path.narrow;
3722 /* only return bytes if they specified a bytes object */
3723 return_str = !(PyBytes_Check(path.object));
3724 }
3725 else {
3726 name = ".";
3727 return_str = 1;
3728 }
3729
Larry Hastings9cf065c2012-06-22 16:30:09 -07003730 Py_BEGIN_ALLOW_THREADS
3731 dirp = opendir(name);
3732 Py_END_ALLOW_THREADS
3733 }
3734
3735 if (dirp == NULL) {
3736 list = path_error("listdir", &path);
Larry Hastings2e3e5932013-08-01 19:34:46 -07003737#ifdef HAVE_FDOPENDIR
3738 if (fd != -1) {
3739 Py_BEGIN_ALLOW_THREADS
3740 close(fd);
3741 Py_END_ALLOW_THREADS
3742 }
3743#endif /* HAVE_FDOPENDIR */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003744 goto exit;
3745 }
3746 if ((list = PyList_New(0)) == NULL) {
3747 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003748 }
3749 for (;;) {
3750 errno = 0;
3751 Py_BEGIN_ALLOW_THREADS
3752 ep = readdir(dirp);
3753 Py_END_ALLOW_THREADS
3754 if (ep == NULL) {
3755 if (errno == 0) {
3756 break;
3757 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003758 Py_DECREF(list);
3759 list = path_error("listdir", &path);
3760 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003761 }
3762 }
3763 if (ep->d_name[0] == '.' &&
3764 (NAMLEN(ep) == 1 ||
3765 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3766 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003767 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003768 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3769 else
3770 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003771 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003772 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003773 break;
3774 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003775 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003776 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003777 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 break;
3779 }
3780 Py_DECREF(v);
3781 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003782
Larry Hastings9cf065c2012-06-22 16:30:09 -07003783exit:
3784 if (dirp != NULL) {
3785 Py_BEGIN_ALLOW_THREADS
Larry Hastings2e3e5932013-08-01 19:34:46 -07003786#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003787 if (fd > -1)
3788 rewinddir(dirp);
Larry Hastings2e3e5932013-08-01 19:34:46 -07003789#endif /* HAVE_FDOPENDIR */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003790 closedir(dirp);
3791 Py_END_ALLOW_THREADS
3792 }
3793
3794 path_cleanup(&path);
3795
3796 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003797
Tim Peters0bb44a42000-09-15 07:44:49 +00003798#endif /* which OS */
3799} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003800
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003801#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003802/* A helper function for abspath on win32 */
3803static PyObject *
3804posix__getfullpathname(PyObject *self, PyObject *args)
3805{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003806 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003807 char outbuf[MAX_PATH*2];
3808 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003809 PyObject *po;
3810
3811 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3812 {
3813 wchar_t *wpath;
3814 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3815 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003816 DWORD result;
3817 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003818
3819 wpath = PyUnicode_AsUnicode(po);
3820 if (wpath == NULL)
3821 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003822 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003823 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003824 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003825 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003826 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003827 if (!woutbufp)
3828 return PyErr_NoMemory();
3829 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3830 }
3831 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003832 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003833 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003834 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003835 if (woutbufp != woutbuf)
3836 free(woutbufp);
3837 return v;
3838 }
3839 /* Drop the argument parsing error as narrow strings
3840 are also valid. */
3841 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003842
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003843 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3844 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003845 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003846 if (win32_warn_bytes_api())
3847 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003848 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003849 outbuf, &temp)) {
3850 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003851 return NULL;
3852 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003853 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3854 return PyUnicode_Decode(outbuf, strlen(outbuf),
3855 Py_FileSystemDefaultEncoding, NULL);
3856 }
3857 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003858} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003859
Brian Curtind25aef52011-06-13 15:16:04 -05003860
Brian Curtinf5e76d02010-11-24 13:14:05 +00003861
Brian Curtind40e6f72010-07-08 21:39:08 +00003862/* A helper function for samepath on windows */
3863static PyObject *
3864posix__getfinalpathname(PyObject *self, PyObject *args)
3865{
3866 HANDLE hFile;
3867 int buf_size;
3868 wchar_t *target_path;
3869 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003870 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003871 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003872
Victor Stinnereb5657a2011-09-30 01:44:27 +02003873 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003874 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003875 path = PyUnicode_AsUnicode(po);
3876 if (path == NULL)
3877 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003878
3879 if(!check_GetFinalPathNameByHandle()) {
3880 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3881 NotImplementedError. */
3882 return PyErr_Format(PyExc_NotImplementedError,
3883 "GetFinalPathNameByHandle not available on this platform");
3884 }
3885
3886 hFile = CreateFileW(
3887 path,
3888 0, /* desired access */
3889 0, /* share mode */
3890 NULL, /* security attributes */
3891 OPEN_EXISTING,
3892 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3893 FILE_FLAG_BACKUP_SEMANTICS,
3894 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003895
Victor Stinnereb5657a2011-09-30 01:44:27 +02003896 if(hFile == INVALID_HANDLE_VALUE)
3897 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003898
3899 /* We have a good handle to the target, use it to determine the
3900 target path name. */
3901 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3902
3903 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003904 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003905
3906 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3907 if(!target_path)
3908 return PyErr_NoMemory();
3909
3910 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3911 buf_size, VOLUME_NAME_DOS);
3912 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003913 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003914
3915 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003916 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003917
3918 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003919 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003920 free(target_path);
3921 return result;
3922
3923} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003924
3925static PyObject *
3926posix__getfileinformation(PyObject *self, PyObject *args)
3927{
3928 HANDLE hFile;
3929 BY_HANDLE_FILE_INFORMATION info;
3930 int fd;
3931
3932 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3933 return NULL;
3934
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003935 if (!_PyVerify_fd(fd))
3936 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003937
3938 hFile = (HANDLE)_get_osfhandle(fd);
3939 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003940 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003941
3942 if (!GetFileInformationByHandle(hFile, &info))
3943 return win32_error("_getfileinformation", NULL);
3944
3945 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3946 info.nFileIndexHigh,
3947 info.nFileIndexLow);
3948}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003949
Brian Curtin95d028f2011-06-09 09:10:38 -05003950PyDoc_STRVAR(posix__isdir__doc__,
3951"Return true if the pathname refers to an existing directory.");
3952
Brian Curtin9c669cc2011-06-08 18:17:18 -05003953static PyObject *
3954posix__isdir(PyObject *self, PyObject *args)
3955{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003956 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003957 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003958 DWORD attributes;
3959
3960 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003961 wchar_t *wpath = PyUnicode_AsUnicode(po);
3962 if (wpath == NULL)
3963 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003964
3965 attributes = GetFileAttributesW(wpath);
3966 if (attributes == INVALID_FILE_ATTRIBUTES)
3967 Py_RETURN_FALSE;
3968 goto check;
3969 }
3970 /* Drop the argument parsing error as narrow strings
3971 are also valid. */
3972 PyErr_Clear();
3973
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003974 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003975 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003976 if (win32_warn_bytes_api())
3977 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003978 attributes = GetFileAttributesA(path);
3979 if (attributes == INVALID_FILE_ATTRIBUTES)
3980 Py_RETURN_FALSE;
3981
3982check:
3983 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3984 Py_RETURN_TRUE;
3985 else
3986 Py_RETURN_FALSE;
3987}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003988#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003989
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003990PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003991"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3992Create a directory.\n\
3993\n\
3994If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3995 and path should be relative; path will then be relative to that directory.\n\
3996dir_fd may not be implemented on your platform.\n\
3997 If it is unavailable, using it will raise a NotImplementedError.\n\
3998\n\
3999The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004000
Barry Warsaw53699e91996-12-10 23:23:01 +00004001static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004002posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004003{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004004 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006 int dir_fd = DEFAULT_DIR_FD;
4007 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
4008 PyObject *return_value = NULL;
4009 int result;
4010
4011 memset(&path, 0, sizeof(path));
4012 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4013 path_converter, &path, &mode,
4014#ifdef HAVE_MKDIRAT
4015 dir_fd_converter, &dir_fd
4016#else
4017 dir_fd_unavailable, &dir_fd
4018#endif
4019 ))
4020 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004021
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004022#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004023 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004024 if (path.wide)
4025 result = CreateDirectoryW(path.wide, NULL);
4026 else
4027 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004028 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004029
Larry Hastings9cf065c2012-06-22 16:30:09 -07004030 if (!result) {
4031 return_value = win32_error_object("mkdir", path.object);
4032 goto exit;
4033 }
4034#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004035 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004036#if HAVE_MKDIRAT
4037 if (dir_fd != DEFAULT_DIR_FD)
4038 result = mkdirat(dir_fd, path.narrow, mode);
4039 else
4040#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004041#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004042 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004043#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004044 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004045#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004047 if (result < 0) {
4048 return_value = path_error("mkdir", &path);
4049 goto exit;
4050 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004051#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004052 return_value = Py_None;
4053 Py_INCREF(Py_None);
4054exit:
4055 path_cleanup(&path);
4056 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004057}
4058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004059
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004060/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4061#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004062#include <sys/resource.h>
4063#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004064
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004065
4066#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004067PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004068"nice(inc) -> new_priority\n\n\
4069Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004070
Barry Warsaw53699e91996-12-10 23:23:01 +00004071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004072posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004073{
Victor Stinner8c62be82010-05-06 00:08:46 +00004074 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004075
Victor Stinner8c62be82010-05-06 00:08:46 +00004076 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4077 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004078
Victor Stinner8c62be82010-05-06 00:08:46 +00004079 /* There are two flavours of 'nice': one that returns the new
4080 priority (as required by almost all standards out there) and the
4081 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4082 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004083
Victor Stinner8c62be82010-05-06 00:08:46 +00004084 If we are of the nice family that returns the new priority, we
4085 need to clear errno before the call, and check if errno is filled
4086 before calling posix_error() on a returnvalue of -1, because the
4087 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004088
Victor Stinner8c62be82010-05-06 00:08:46 +00004089 errno = 0;
4090 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004091#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004092 if (value == 0)
4093 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004094#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004095 if (value == -1 && errno != 0)
4096 /* either nice() or getpriority() returned an error */
4097 return posix_error();
4098 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004099}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004100#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004101
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004102
4103#ifdef HAVE_GETPRIORITY
4104PyDoc_STRVAR(posix_getpriority__doc__,
4105"getpriority(which, who) -> current_priority\n\n\
4106Get program scheduling priority.");
4107
4108static PyObject *
4109posix_getpriority(PyObject *self, PyObject *args)
4110{
4111 int which, who, retval;
4112
4113 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4114 return NULL;
4115 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004116 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004117 if (errno != 0)
4118 return posix_error();
4119 return PyLong_FromLong((long)retval);
4120}
4121#endif /* HAVE_GETPRIORITY */
4122
4123
4124#ifdef HAVE_SETPRIORITY
4125PyDoc_STRVAR(posix_setpriority__doc__,
4126"setpriority(which, who, prio) -> None\n\n\
4127Set program scheduling priority.");
4128
4129static PyObject *
4130posix_setpriority(PyObject *self, PyObject *args)
4131{
4132 int which, who, prio, retval;
4133
4134 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4135 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004136 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004137 if (retval == -1)
4138 return posix_error();
4139 Py_RETURN_NONE;
4140}
4141#endif /* HAVE_SETPRIORITY */
4142
4143
Barry Warsaw53699e91996-12-10 23:23:01 +00004144static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004146{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004147 char *function_name = is_replace ? "replace" : "rename";
4148 path_t src;
4149 path_t dst;
4150 int src_dir_fd = DEFAULT_DIR_FD;
4151 int dst_dir_fd = DEFAULT_DIR_FD;
4152 int dir_fd_specified;
4153 PyObject *return_value = NULL;
4154 char format[24];
4155 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4156
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004157#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004158 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004159 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004160#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004161 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004162#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004163
4164 memset(&src, 0, sizeof(src));
4165 memset(&dst, 0, sizeof(dst));
4166 strcpy(format, "O&O&|$O&O&:");
4167 strcat(format, function_name);
4168 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4169 path_converter, &src,
4170 path_converter, &dst,
4171 dir_fd_converter, &src_dir_fd,
4172 dir_fd_converter, &dst_dir_fd))
4173 return NULL;
4174
4175 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4176 (dst_dir_fd != DEFAULT_DIR_FD);
4177#ifndef HAVE_RENAMEAT
4178 if (dir_fd_specified) {
4179 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4180 goto exit;
4181 }
4182#endif
4183
4184 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4185 PyErr_Format(PyExc_ValueError,
4186 "%s: src and dst must be the same type", function_name);
4187 goto exit;
4188 }
4189
4190#ifdef MS_WINDOWS
4191 Py_BEGIN_ALLOW_THREADS
4192 if (src.wide)
4193 result = MoveFileExW(src.wide, dst.wide, flags);
4194 else
4195 result = MoveFileExA(src.narrow, dst.narrow, flags);
4196 Py_END_ALLOW_THREADS
4197
4198 if (!result) {
4199 return_value = win32_error_object(function_name, dst.object);
4200 goto exit;
4201 }
4202
4203#else
4204 Py_BEGIN_ALLOW_THREADS
4205#ifdef HAVE_RENAMEAT
4206 if (dir_fd_specified)
4207 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4208 else
4209#endif
4210 result = rename(src.narrow, dst.narrow);
4211 Py_END_ALLOW_THREADS
4212
4213 if (result) {
4214 return_value = path_error(function_name, &dst);
4215 goto exit;
4216 }
4217#endif
4218
4219 Py_INCREF(Py_None);
4220 return_value = Py_None;
4221exit:
4222 path_cleanup(&src);
4223 path_cleanup(&dst);
4224 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004225}
4226
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004227PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004228"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4229Rename a file or directory.\n\
4230\n\
4231If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4232 descriptor open to a directory, and the respective path string (src or dst)\n\
4233 should be relative; the path will then be relative to that directory.\n\
4234src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4235 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004236
4237static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004238posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004239{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004240 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004241}
4242
4243PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4245Rename a file or directory, overwriting the destination.\n\
4246\n\
4247If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4248 descriptor open to a directory, and the respective path string (src or dst)\n\
4249 should be relative; the path will then be relative to that directory.\n\
4250src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4251 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004252
4253static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004254posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004255{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004256 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004257}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004259PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004260"rmdir(path, *, dir_fd=None)\n\n\
4261Remove a directory.\n\
4262\n\
4263If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4264 and path should be relative; path will then be relative to that directory.\n\
4265dir_fd may not be implemented on your platform.\n\
4266 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Barry Warsaw53699e91996-12-10 23:23:01 +00004268static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004269posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004270{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004271 path_t path;
4272 int dir_fd = DEFAULT_DIR_FD;
4273 static char *keywords[] = {"path", "dir_fd", NULL};
4274 int result;
4275 PyObject *return_value = NULL;
4276
4277 memset(&path, 0, sizeof(path));
4278 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4279 path_converter, &path,
4280#ifdef HAVE_UNLINKAT
4281 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004282#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004283 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004284#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004285 ))
4286 return NULL;
4287
4288 Py_BEGIN_ALLOW_THREADS
4289#ifdef MS_WINDOWS
4290 if (path.wide)
4291 result = RemoveDirectoryW(path.wide);
4292 else
4293 result = RemoveDirectoryA(path.narrow);
4294 result = !result; /* Windows, success=1, UNIX, success=0 */
4295#else
4296#ifdef HAVE_UNLINKAT
4297 if (dir_fd != DEFAULT_DIR_FD)
4298 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4299 else
4300#endif
4301 result = rmdir(path.narrow);
4302#endif
4303 Py_END_ALLOW_THREADS
4304
4305 if (result) {
4306 return_value = path_error("rmdir", &path);
4307 goto exit;
4308 }
4309
4310 return_value = Py_None;
4311 Py_INCREF(Py_None);
4312
4313exit:
4314 path_cleanup(&path);
4315 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004316}
4317
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004318
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004319#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004320PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004321"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004322Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004323
Barry Warsaw53699e91996-12-10 23:23:01 +00004324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004325posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004326{
Victor Stinner8c62be82010-05-06 00:08:46 +00004327 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004328#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004329 wchar_t *command;
4330 if (!PyArg_ParseTuple(args, "u:system", &command))
4331 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004332
Victor Stinner8c62be82010-05-06 00:08:46 +00004333 Py_BEGIN_ALLOW_THREADS
4334 sts = _wsystem(command);
4335 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004336#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004337 PyObject *command_obj;
4338 char *command;
4339 if (!PyArg_ParseTuple(args, "O&:system",
4340 PyUnicode_FSConverter, &command_obj))
4341 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004342
Victor Stinner8c62be82010-05-06 00:08:46 +00004343 command = PyBytes_AsString(command_obj);
4344 Py_BEGIN_ALLOW_THREADS
4345 sts = system(command);
4346 Py_END_ALLOW_THREADS
4347 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004348#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004349 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004350}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004351#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004353
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004354PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004355"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004356Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004357
Barry Warsaw53699e91996-12-10 23:23:01 +00004358static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004359posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004360{
Victor Stinner8c62be82010-05-06 00:08:46 +00004361 int i;
4362 if (!PyArg_ParseTuple(args, "i:umask", &i))
4363 return NULL;
4364 i = (int)umask(i);
4365 if (i < 0)
4366 return posix_error();
4367 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004368}
4369
Brian Curtind40e6f72010-07-08 21:39:08 +00004370#ifdef MS_WINDOWS
4371
4372/* override the default DeleteFileW behavior so that directory
4373symlinks can be removed with this function, the same as with
4374Unix symlinks */
4375BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4376{
4377 WIN32_FILE_ATTRIBUTE_DATA info;
4378 WIN32_FIND_DATAW find_data;
4379 HANDLE find_data_handle;
4380 int is_directory = 0;
4381 int is_link = 0;
4382
4383 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4384 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004385
Brian Curtind40e6f72010-07-08 21:39:08 +00004386 /* Get WIN32_FIND_DATA structure for the path to determine if
4387 it is a symlink */
4388 if(is_directory &&
4389 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4390 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4391
4392 if(find_data_handle != INVALID_HANDLE_VALUE) {
4393 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4394 FindClose(find_data_handle);
4395 }
4396 }
4397 }
4398
4399 if (is_directory && is_link)
4400 return RemoveDirectoryW(lpFileName);
4401
4402 return DeleteFileW(lpFileName);
4403}
4404#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004405
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004406PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004407"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004408Remove a file (same as remove()).\n\
4409\n\
4410If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4411 and path should be relative; path will then be relative to that directory.\n\
4412dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004413 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004414
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004415PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004416"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004417Remove a file (same as unlink()).\n\
4418\n\
4419If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4420 and path should be relative; path will then be relative to that directory.\n\
4421dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004422 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004423
Barry Warsaw53699e91996-12-10 23:23:01 +00004424static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004425posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004426{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004427 path_t path;
4428 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004429 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004430 int result;
4431 PyObject *return_value = NULL;
4432
4433 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004434 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004435 path_converter, &path,
4436#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004437 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004438#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004439 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004440#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004441 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004442 return NULL;
4443
4444 Py_BEGIN_ALLOW_THREADS
4445#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004446 if (path.wide)
4447 result = Py_DeleteFileW(path.wide);
4448 else
4449 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004450 result = !result; /* Windows, success=1, UNIX, success=0 */
4451#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004452#ifdef HAVE_UNLINKAT
4453 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004454 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004455 else
4456#endif /* HAVE_UNLINKAT */
4457 result = unlink(path.narrow);
4458#endif
4459 Py_END_ALLOW_THREADS
4460
4461 if (result) {
4462 return_value = path_error("unlink", &path);
4463 goto exit;
4464 }
4465
4466 return_value = Py_None;
4467 Py_INCREF(Py_None);
4468
4469exit:
4470 path_cleanup(&path);
4471 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004472}
4473
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004474
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004475PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004476"uname() -> uname_result\n\n\
4477Return an object identifying the current operating system.\n\
4478The object behaves like a named tuple with the following fields:\n\
4479 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004480
Larry Hastings605a62d2012-06-24 04:33:36 -07004481static PyStructSequence_Field uname_result_fields[] = {
4482 {"sysname", "operating system name"},
4483 {"nodename", "name of machine on network (implementation-defined)"},
4484 {"release", "operating system release"},
4485 {"version", "operating system version"},
4486 {"machine", "hardware identifier"},
4487 {NULL}
4488};
4489
4490PyDoc_STRVAR(uname_result__doc__,
4491"uname_result: Result from os.uname().\n\n\
4492This object may be accessed either as a tuple of\n\
4493 (sysname, nodename, release, version, machine),\n\
4494or via the attributes sysname, nodename, release, version, and machine.\n\
4495\n\
4496See os.uname for more information.");
4497
4498static PyStructSequence_Desc uname_result_desc = {
4499 "uname_result", /* name */
4500 uname_result__doc__, /* doc */
4501 uname_result_fields,
4502 5
4503};
4504
4505static PyTypeObject UnameResultType;
4506
4507
4508#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004509static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004510posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004511{
Victor Stinner8c62be82010-05-06 00:08:46 +00004512 struct utsname u;
4513 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004514 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004515
Victor Stinner8c62be82010-05-06 00:08:46 +00004516 Py_BEGIN_ALLOW_THREADS
4517 res = uname(&u);
4518 Py_END_ALLOW_THREADS
4519 if (res < 0)
4520 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004521
4522 value = PyStructSequence_New(&UnameResultType);
4523 if (value == NULL)
4524 return NULL;
4525
4526#define SET(i, field) \
4527 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004528 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004529 if (!o) { \
4530 Py_DECREF(value); \
4531 return NULL; \
4532 } \
4533 PyStructSequence_SET_ITEM(value, i, o); \
4534 } \
4535
4536 SET(0, u.sysname);
4537 SET(1, u.nodename);
4538 SET(2, u.release);
4539 SET(3, u.version);
4540 SET(4, u.machine);
4541
4542#undef SET
4543
4544 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004545}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004546#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004547
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004548
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549PyDoc_STRVAR(posix_utime__doc__,
4550"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4551Set the access and modified time of path.\n\
4552\n\
4553path may always be specified as a string.\n\
4554On some platforms, path may also be specified as an open file descriptor.\n\
4555 If this functionality is unavailable, using it raises an exception.\n\
4556\n\
4557If times is not None, it must be a tuple (atime, mtime);\n\
4558 atime and mtime should be expressed as float seconds since the epoch.\n\
4559If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4560 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4561 since the epoch.\n\
4562If both times and ns are None, utime uses the current time.\n\
4563Specifying tuples for both times and ns is an error.\n\
4564\n\
4565If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4566 and path should be relative; path will then be relative to that directory.\n\
4567If follow_symlinks is False, and the last element of the path is a symbolic\n\
4568 link, utime will modify the symbolic link itself instead of the file the\n\
4569 link points to.\n\
4570It is an error to use dir_fd or follow_symlinks when specifying path\n\
4571 as an open file descriptor.\n\
4572dir_fd and follow_symlinks may not be available on your platform.\n\
4573 If they are unavailable, using them will raise a NotImplementedError.");
4574
4575typedef struct {
4576 int now;
4577 time_t atime_s;
4578 long atime_ns;
4579 time_t mtime_s;
4580 long mtime_ns;
4581} utime_t;
4582
4583/*
4584 * these macros assume that "utime" is a pointer to a utime_t
4585 * they also intentionally leak the declaration of a pointer named "time"
4586 */
4587#define UTIME_TO_TIMESPEC \
4588 struct timespec ts[2]; \
4589 struct timespec *time; \
4590 if (utime->now) \
4591 time = NULL; \
4592 else { \
4593 ts[0].tv_sec = utime->atime_s; \
4594 ts[0].tv_nsec = utime->atime_ns; \
4595 ts[1].tv_sec = utime->mtime_s; \
4596 ts[1].tv_nsec = utime->mtime_ns; \
4597 time = ts; \
4598 } \
4599
4600#define UTIME_TO_TIMEVAL \
4601 struct timeval tv[2]; \
4602 struct timeval *time; \
4603 if (utime->now) \
4604 time = NULL; \
4605 else { \
4606 tv[0].tv_sec = utime->atime_s; \
4607 tv[0].tv_usec = utime->atime_ns / 1000; \
4608 tv[1].tv_sec = utime->mtime_s; \
4609 tv[1].tv_usec = utime->mtime_ns / 1000; \
4610 time = tv; \
4611 } \
4612
4613#define UTIME_TO_UTIMBUF \
4614 struct utimbuf u[2]; \
4615 struct utimbuf *time; \
4616 if (utime->now) \
4617 time = NULL; \
4618 else { \
4619 u.actime = utime->atime_s; \
4620 u.modtime = utime->mtime_s; \
4621 time = u; \
4622 }
4623
4624#define UTIME_TO_TIME_T \
4625 time_t timet[2]; \
4626 struct timet time; \
4627 if (utime->now) \
4628 time = NULL; \
4629 else { \
4630 timet[0] = utime->atime_s; \
4631 timet[1] = utime->mtime_s; \
4632 time = &timet; \
4633 } \
4634
4635
4636#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4637
4638#if UTIME_HAVE_DIR_FD
4639
4640static int
4641utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4642{
4643#ifdef HAVE_UTIMENSAT
4644 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4645 UTIME_TO_TIMESPEC;
4646 return utimensat(dir_fd, path, time, flags);
4647#elif defined(HAVE_FUTIMESAT)
4648 UTIME_TO_TIMEVAL;
4649 /*
4650 * follow_symlinks will never be false here;
4651 * we only allow !follow_symlinks and dir_fd together
4652 * if we have utimensat()
4653 */
4654 assert(follow_symlinks);
4655 return futimesat(dir_fd, path, time);
4656#endif
4657}
4658
4659#endif
4660
4661#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4662
4663#if UTIME_HAVE_FD
4664
4665static int
4666utime_fd(utime_t *utime, int fd)
4667{
4668#ifdef HAVE_FUTIMENS
4669 UTIME_TO_TIMESPEC;
4670 return futimens(fd, time);
4671#else
4672 UTIME_TO_TIMEVAL;
4673 return futimes(fd, time);
4674#endif
4675}
4676
4677#endif
4678
4679
4680#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4681 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4682
4683#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4684
4685static int
4686utime_nofollow_symlinks(utime_t *utime, char *path)
4687{
4688#ifdef HAVE_UTIMENSAT
4689 UTIME_TO_TIMESPEC;
4690 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4691#else
4692 UTIME_TO_TIMEVAL;
4693 return lutimes(path, time);
4694#endif
4695}
4696
4697#endif
4698
4699#ifndef MS_WINDOWS
4700
4701static int
4702utime_default(utime_t *utime, char *path)
4703{
4704#ifdef HAVE_UTIMENSAT
4705 UTIME_TO_TIMESPEC;
4706 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4707#elif defined(HAVE_UTIMES)
4708 UTIME_TO_TIMEVAL;
4709 return utimes(path, time);
4710#elif defined(HAVE_UTIME_H)
4711 UTIME_TO_UTIMBUF;
4712 return utime(path, time);
4713#else
4714 UTIME_TO_TIME_T;
4715 return utime(path, time);
4716#endif
4717}
4718
4719#endif
4720
Larry Hastings76ad59b2012-05-03 00:30:07 -07004721static int
4722split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4723{
4724 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004725 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004726 divmod = PyNumber_Divmod(py_long, billion);
4727 if (!divmod)
4728 goto exit;
4729 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4730 if ((*s == -1) && PyErr_Occurred())
4731 goto exit;
4732 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004733 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004734 goto exit;
4735
4736 result = 1;
4737exit:
4738 Py_XDECREF(divmod);
4739 return result;
4740}
4741
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742static PyObject *
4743posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004744{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004746 PyObject *times = NULL;
4747 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 int dir_fd = DEFAULT_DIR_FD;
4749 int follow_symlinks = 1;
4750 char *keywords[] = {"path", "times", "ns", "dir_fd",
4751 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004752
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004754
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755#ifdef MS_WINDOWS
4756 HANDLE hFile;
4757 FILETIME atime, mtime;
4758#else
4759 int result;
4760#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004761
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004763
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 memset(&path, 0, sizeof(path));
Christian Heimesb3c87242013-08-01 00:08:16 +02004765 memset(&utime, 0, sizeof(utime_t));
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766#if UTIME_HAVE_FD
4767 path.allow_fd = 1;
4768#endif
4769 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4770 "O&|O$OO&p:utime", keywords,
4771 path_converter, &path,
4772 &times, &ns,
4773#if UTIME_HAVE_DIR_FD
4774 dir_fd_converter, &dir_fd,
4775#else
4776 dir_fd_unavailable, &dir_fd,
4777#endif
4778 &follow_symlinks
4779 ))
4780 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004781
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 if (times && (times != Py_None) && ns) {
4783 PyErr_SetString(PyExc_ValueError,
4784 "utime: you may specify either 'times'"
4785 " or 'ns' but not both");
4786 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004787 }
4788
4789 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004790 time_t a_sec, m_sec;
4791 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004792 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004793 PyErr_SetString(PyExc_TypeError,
4794 "utime: 'times' must be either"
4795 " a tuple of two ints or None");
4796 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004797 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004798 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004799 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004800 &a_sec, &a_nsec) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004801 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004802 &m_sec, &m_nsec) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004804 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004805 utime.atime_s = a_sec;
4806 utime.atime_ns = a_nsec;
4807 utime.mtime_s = m_sec;
4808 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004809 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004810 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004811 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812 PyErr_SetString(PyExc_TypeError,
4813 "utime: 'ns' must be a tuple of two ints");
4814 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004815 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004816 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004817 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004818 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004819 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004820 &utime.mtime_s, &utime.mtime_ns)) {
4821 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004822 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004823 }
4824 else {
4825 /* times and ns are both None/unspecified. use "now". */
4826 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004827 }
4828
Larry Hastings9cf065c2012-06-22 16:30:09 -07004829#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4830 if (follow_symlinks_specified("utime", follow_symlinks))
4831 goto exit;
4832#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004833
Larry Hastings9cf065c2012-06-22 16:30:09 -07004834 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4835 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4836 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4837 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004838
Larry Hastings9cf065c2012-06-22 16:30:09 -07004839#if !defined(HAVE_UTIMENSAT)
4840 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004841 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842 "utime: cannot use dir_fd and follow_symlinks "
4843 "together on this platform");
4844 goto exit;
4845 }
4846#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004847
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004848#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004849 Py_BEGIN_ALLOW_THREADS
4850 if (path.wide)
4851 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004852 NULL, OPEN_EXISTING,
4853 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854 else
4855 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 NULL, OPEN_EXISTING,
4857 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858 Py_END_ALLOW_THREADS
4859 if (hFile == INVALID_HANDLE_VALUE) {
4860 win32_error_object("utime", path.object);
4861 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004862 }
4863
Larry Hastings9cf065c2012-06-22 16:30:09 -07004864 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004865 SYSTEMTIME now;
4866 GetSystemTime(&now);
4867 if (!SystemTimeToFileTime(&now, &mtime) ||
4868 !SystemTimeToFileTime(&now, &atime)) {
4869 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004870 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004871 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004874 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4875 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 }
4877 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4878 /* Avoid putting the file name into the error here,
4879 as that may confuse the user into believing that
4880 something is wrong with the file, when it also
4881 could be the time stamp that gives a problem. */
4882 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004884 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004885#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004886 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004887
Larry Hastings9cf065c2012-06-22 16:30:09 -07004888#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4889 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4890 result = utime_nofollow_symlinks(&utime, path.narrow);
4891 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004892#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004893
4894#if UTIME_HAVE_DIR_FD
4895 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4896 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4897 else
4898#endif
4899
4900#if UTIME_HAVE_FD
4901 if (path.fd != -1)
4902 result = utime_fd(&utime, path.fd);
4903 else
4904#endif
4905
4906 result = utime_default(&utime, path.narrow);
4907
4908 Py_END_ALLOW_THREADS
4909
4910 if (result < 0) {
4911 /* see previous comment about not putting filename in error here */
4912 return_value = posix_error();
4913 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004915
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004916#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004917
4918 Py_INCREF(Py_None);
4919 return_value = Py_None;
4920
4921exit:
4922 path_cleanup(&path);
4923#ifdef MS_WINDOWS
4924 if (hFile != INVALID_HANDLE_VALUE)
4925 CloseHandle(hFile);
4926#endif
4927 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004928}
4929
Guido van Rossum3b066191991-06-04 19:40:25 +00004930/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004931
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004932PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004933"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004935
Barry Warsaw53699e91996-12-10 23:23:01 +00004936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004937posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004938{
Victor Stinner8c62be82010-05-06 00:08:46 +00004939 int sts;
4940 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4941 return NULL;
4942 _exit(sts);
4943 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004944}
4945
Martin v. Löwis114619e2002-10-07 06:44:21 +00004946#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4947static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004948free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004949{
Victor Stinner8c62be82010-05-06 00:08:46 +00004950 Py_ssize_t i;
4951 for (i = 0; i < count; i++)
4952 PyMem_Free(array[i]);
4953 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004954}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004955
Antoine Pitrou69f71142009-05-24 21:25:49 +00004956static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004957int fsconvert_strdup(PyObject *o, char**out)
4958{
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 PyObject *bytes;
4960 Py_ssize_t size;
4961 if (!PyUnicode_FSConverter(o, &bytes))
4962 return 0;
4963 size = PyBytes_GET_SIZE(bytes);
4964 *out = PyMem_Malloc(size+1);
4965 if (!*out)
4966 return 0;
4967 memcpy(*out, PyBytes_AsString(bytes), size+1);
4968 Py_DECREF(bytes);
4969 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004970}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004971#endif
4972
Ross Lagerwall7807c352011-03-17 20:20:30 +02004973#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004974static char**
4975parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4976{
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 char **envlist;
4978 Py_ssize_t i, pos, envc;
4979 PyObject *keys=NULL, *vals=NULL;
4980 PyObject *key, *val, *key2, *val2;
4981 char *p, *k, *v;
4982 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004983
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 i = PyMapping_Size(env);
4985 if (i < 0)
4986 return NULL;
4987 envlist = PyMem_NEW(char *, i + 1);
4988 if (envlist == NULL) {
4989 PyErr_NoMemory();
4990 return NULL;
4991 }
4992 envc = 0;
4993 keys = PyMapping_Keys(env);
4994 vals = PyMapping_Values(env);
4995 if (!keys || !vals)
4996 goto error;
4997 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4998 PyErr_Format(PyExc_TypeError,
4999 "env.keys() or env.values() is not a list");
5000 goto error;
5001 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005002
Victor Stinner8c62be82010-05-06 00:08:46 +00005003 for (pos = 0; pos < i; pos++) {
5004 key = PyList_GetItem(keys, pos);
5005 val = PyList_GetItem(vals, pos);
5006 if (!key || !val)
5007 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005008
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 if (PyUnicode_FSConverter(key, &key2) == 0)
5010 goto error;
5011 if (PyUnicode_FSConverter(val, &val2) == 0) {
5012 Py_DECREF(key2);
5013 goto error;
5014 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005015
5016#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
5018 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00005019#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 k = PyBytes_AsString(key2);
5021 v = PyBytes_AsString(val2);
5022 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005023
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 p = PyMem_NEW(char, len);
5025 if (p == NULL) {
5026 PyErr_NoMemory();
5027 Py_DECREF(key2);
5028 Py_DECREF(val2);
5029 goto error;
5030 }
5031 PyOS_snprintf(p, len, "%s=%s", k, v);
5032 envlist[envc++] = p;
5033 Py_DECREF(key2);
5034 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005035#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00005036 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005037#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005038 }
5039 Py_DECREF(vals);
5040 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005041
Victor Stinner8c62be82010-05-06 00:08:46 +00005042 envlist[envc] = 0;
5043 *envc_ptr = envc;
5044 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005045
5046error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005047 Py_XDECREF(keys);
5048 Py_XDECREF(vals);
5049 while (--envc >= 0)
5050 PyMem_DEL(envlist[envc]);
5051 PyMem_DEL(envlist);
5052 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005053}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005054
Ross Lagerwall7807c352011-03-17 20:20:30 +02005055static char**
5056parse_arglist(PyObject* argv, Py_ssize_t *argc)
5057{
5058 int i;
5059 char **argvlist = PyMem_NEW(char *, *argc+1);
5060 if (argvlist == NULL) {
5061 PyErr_NoMemory();
5062 return NULL;
5063 }
5064 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005065 PyObject* item = PySequence_ITEM(argv, i);
5066 if (item == NULL)
5067 goto fail;
5068 if (!fsconvert_strdup(item, &argvlist[i])) {
5069 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070 goto fail;
5071 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005072 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005073 }
5074 argvlist[*argc] = NULL;
5075 return argvlist;
5076fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005077 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005078 free_string_array(argvlist, *argc);
5079 return NULL;
5080}
5081#endif
5082
5083#ifdef HAVE_EXECV
5084PyDoc_STRVAR(posix_execv__doc__,
5085"execv(path, args)\n\n\
5086Execute an executable path with arguments, replacing current process.\n\
5087\n\
5088 path: path of executable file\n\
5089 args: tuple or list of strings");
5090
5091static PyObject *
5092posix_execv(PyObject *self, PyObject *args)
5093{
5094 PyObject *opath;
5095 char *path;
5096 PyObject *argv;
5097 char **argvlist;
5098 Py_ssize_t argc;
5099
5100 /* execv has two arguments: (path, argv), where
5101 argv is a list or tuple of strings. */
5102
5103 if (!PyArg_ParseTuple(args, "O&O:execv",
5104 PyUnicode_FSConverter,
5105 &opath, &argv))
5106 return NULL;
5107 path = PyBytes_AsString(opath);
5108 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5109 PyErr_SetString(PyExc_TypeError,
5110 "execv() arg 2 must be a tuple or list");
5111 Py_DECREF(opath);
5112 return NULL;
5113 }
5114 argc = PySequence_Size(argv);
5115 if (argc < 1) {
5116 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5117 Py_DECREF(opath);
5118 return NULL;
5119 }
5120
5121 argvlist = parse_arglist(argv, &argc);
5122 if (argvlist == NULL) {
5123 Py_DECREF(opath);
5124 return NULL;
5125 }
5126
5127 execv(path, argvlist);
5128
5129 /* If we get here it's definitely an error */
5130
5131 free_string_array(argvlist, argc);
5132 Py_DECREF(opath);
5133 return posix_error();
5134}
5135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005136PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005137"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005138Execute a path with arguments and environment, replacing current process.\n\
5139\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 path: path of executable file\n\
5141 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005142 env: dictionary of strings mapping to strings\n\
5143\n\
5144On some platforms, you may specify an open file descriptor for path;\n\
5145 execve will execute the program the file descriptor is open to.\n\
5146 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005147
Barry Warsaw53699e91996-12-10 23:23:01 +00005148static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005149posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005150{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005151 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005153 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005154 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005155 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005157
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 /* execve has three arguments: (path, argv, env), where
5159 argv is a list or tuple of strings and env is a dictionary
5160 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005161
Larry Hastings9cf065c2012-06-22 16:30:09 -07005162 memset(&path, 0, sizeof(path));
5163#ifdef HAVE_FEXECVE
5164 path.allow_fd = 1;
5165#endif
5166 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5167 path_converter, &path,
5168 &argv, &env
5169 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005171
Ross Lagerwall7807c352011-03-17 20:20:30 +02005172 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005174 "execve: argv must be a tuple or list");
5175 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005176 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005177 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 if (!PyMapping_Check(env)) {
5179 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005180 "execve: environment must be a mapping object");
5181 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005182 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005183
Ross Lagerwall7807c352011-03-17 20:20:30 +02005184 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005186 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005188
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 envlist = parse_envlist(env, &envc);
5190 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005191 goto fail;
5192
Larry Hastings9cf065c2012-06-22 16:30:09 -07005193#ifdef HAVE_FEXECVE
5194 if (path.fd > -1)
5195 fexecve(path.fd, argvlist, envlist);
5196 else
5197#endif
5198 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005199
5200 /* If we get here it's definitely an error */
5201
Larry Hastings9cf065c2012-06-22 16:30:09 -07005202 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005203
5204 while (--envc >= 0)
5205 PyMem_DEL(envlist[envc]);
5206 PyMem_DEL(envlist);
5207 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005208 if (argvlist)
5209 free_string_array(argvlist, argc);
5210 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005211 return NULL;
5212}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005213#endif /* HAVE_EXECV */
5214
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005215
Guido van Rossuma1065681999-01-25 23:20:23 +00005216#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005217PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005218"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005219Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005220\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 mode: mode of process creation\n\
5222 path: path of executable file\n\
5223 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005224
5225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005226posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005227{
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 PyObject *opath;
5229 char *path;
5230 PyObject *argv;
5231 char **argvlist;
5232 int mode, i;
5233 Py_ssize_t argc;
5234 Py_intptr_t spawnval;
5235 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005236
Victor Stinner8c62be82010-05-06 00:08:46 +00005237 /* spawnv has three arguments: (mode, path, argv), where
5238 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005239
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5241 PyUnicode_FSConverter,
5242 &opath, &argv))
5243 return NULL;
5244 path = PyBytes_AsString(opath);
5245 if (PyList_Check(argv)) {
5246 argc = PyList_Size(argv);
5247 getitem = PyList_GetItem;
5248 }
5249 else if (PyTuple_Check(argv)) {
5250 argc = PyTuple_Size(argv);
5251 getitem = PyTuple_GetItem;
5252 }
5253 else {
5254 PyErr_SetString(PyExc_TypeError,
5255 "spawnv() arg 2 must be a tuple or list");
5256 Py_DECREF(opath);
5257 return NULL;
5258 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005259
Victor Stinner8c62be82010-05-06 00:08:46 +00005260 argvlist = PyMem_NEW(char *, argc+1);
5261 if (argvlist == NULL) {
5262 Py_DECREF(opath);
5263 return PyErr_NoMemory();
5264 }
5265 for (i = 0; i < argc; i++) {
5266 if (!fsconvert_strdup((*getitem)(argv, i),
5267 &argvlist[i])) {
5268 free_string_array(argvlist, i);
5269 PyErr_SetString(
5270 PyExc_TypeError,
5271 "spawnv() arg 2 must contain only strings");
5272 Py_DECREF(opath);
5273 return NULL;
5274 }
5275 }
5276 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005277
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005278#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005279 Py_BEGIN_ALLOW_THREADS
5280 spawnval = spawnv(mode, path, argvlist);
5281 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005282#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 if (mode == _OLD_P_OVERLAY)
5284 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005285
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 Py_BEGIN_ALLOW_THREADS
5287 spawnval = _spawnv(mode, path, argvlist);
5288 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005289#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005290
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 free_string_array(argvlist, argc);
5292 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 if (spawnval == -1)
5295 return posix_error();
5296 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005297#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005299#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005301#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005302}
5303
5304
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005305PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005306"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005307Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005308\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 mode: mode of process creation\n\
5310 path: path of executable file\n\
5311 args: tuple or list of arguments\n\
5312 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005313
5314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005315posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005316{
Victor Stinner8c62be82010-05-06 00:08:46 +00005317 PyObject *opath;
5318 char *path;
5319 PyObject *argv, *env;
5320 char **argvlist;
5321 char **envlist;
5322 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005323 int mode;
5324 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 Py_intptr_t spawnval;
5326 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5327 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005328
Victor Stinner8c62be82010-05-06 00:08:46 +00005329 /* spawnve has four arguments: (mode, path, argv, env), where
5330 argv is a list or tuple of strings and env is a dictionary
5331 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005332
Victor Stinner8c62be82010-05-06 00:08:46 +00005333 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5334 PyUnicode_FSConverter,
5335 &opath, &argv, &env))
5336 return NULL;
5337 path = PyBytes_AsString(opath);
5338 if (PyList_Check(argv)) {
5339 argc = PyList_Size(argv);
5340 getitem = PyList_GetItem;
5341 }
5342 else if (PyTuple_Check(argv)) {
5343 argc = PyTuple_Size(argv);
5344 getitem = PyTuple_GetItem;
5345 }
5346 else {
5347 PyErr_SetString(PyExc_TypeError,
5348 "spawnve() arg 2 must be a tuple or list");
5349 goto fail_0;
5350 }
5351 if (!PyMapping_Check(env)) {
5352 PyErr_SetString(PyExc_TypeError,
5353 "spawnve() arg 3 must be a mapping object");
5354 goto fail_0;
5355 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005356
Victor Stinner8c62be82010-05-06 00:08:46 +00005357 argvlist = PyMem_NEW(char *, argc+1);
5358 if (argvlist == NULL) {
5359 PyErr_NoMemory();
5360 goto fail_0;
5361 }
5362 for (i = 0; i < argc; i++) {
5363 if (!fsconvert_strdup((*getitem)(argv, i),
5364 &argvlist[i]))
5365 {
5366 lastarg = i;
5367 goto fail_1;
5368 }
5369 }
5370 lastarg = argc;
5371 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005372
Victor Stinner8c62be82010-05-06 00:08:46 +00005373 envlist = parse_envlist(env, &envc);
5374 if (envlist == NULL)
5375 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005376
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005377#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 Py_BEGIN_ALLOW_THREADS
5379 spawnval = spawnve(mode, path, argvlist, envlist);
5380 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005381#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 if (mode == _OLD_P_OVERLAY)
5383 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005384
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 Py_BEGIN_ALLOW_THREADS
5386 spawnval = _spawnve(mode, path, argvlist, envlist);
5387 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005388#endif
Tim Peters25059d32001-12-07 20:35:43 +00005389
Victor Stinner8c62be82010-05-06 00:08:46 +00005390 if (spawnval == -1)
5391 (void) posix_error();
5392 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005393#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005394 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005395#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005396 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005397#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005398
Victor Stinner8c62be82010-05-06 00:08:46 +00005399 while (--envc >= 0)
5400 PyMem_DEL(envlist[envc]);
5401 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005402 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005403 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005404 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 Py_DECREF(opath);
5406 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005407}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005408
5409/* OS/2 supports spawnvp & spawnvpe natively */
5410#if defined(PYOS_OS2)
5411PyDoc_STRVAR(posix_spawnvp__doc__,
5412"spawnvp(mode, file, args)\n\n\
5413Execute the program 'file' in a new process, using the environment\n\
5414search path to find the file.\n\
5415\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 mode: mode of process creation\n\
5417 file: executable file name\n\
5418 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005419
5420static PyObject *
5421posix_spawnvp(PyObject *self, PyObject *args)
5422{
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 PyObject *opath;
5424 char *path;
5425 PyObject *argv;
5426 char **argvlist;
5427 int mode, i, argc;
5428 Py_intptr_t spawnval;
5429 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005430
Victor Stinner8c62be82010-05-06 00:08:46 +00005431 /* spawnvp has three arguments: (mode, path, argv), where
5432 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005433
Victor Stinner8c62be82010-05-06 00:08:46 +00005434 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5435 PyUnicode_FSConverter,
5436 &opath, &argv))
5437 return NULL;
5438 path = PyBytes_AsString(opath);
5439 if (PyList_Check(argv)) {
5440 argc = PyList_Size(argv);
5441 getitem = PyList_GetItem;
5442 }
5443 else if (PyTuple_Check(argv)) {
5444 argc = PyTuple_Size(argv);
5445 getitem = PyTuple_GetItem;
5446 }
5447 else {
5448 PyErr_SetString(PyExc_TypeError,
5449 "spawnvp() arg 2 must be a tuple or list");
5450 Py_DECREF(opath);
5451 return NULL;
5452 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005453
Victor Stinner8c62be82010-05-06 00:08:46 +00005454 argvlist = PyMem_NEW(char *, argc+1);
5455 if (argvlist == NULL) {
5456 Py_DECREF(opath);
5457 return PyErr_NoMemory();
5458 }
5459 for (i = 0; i < argc; i++) {
5460 if (!fsconvert_strdup((*getitem)(argv, i),
5461 &argvlist[i])) {
5462 free_string_array(argvlist, i);
5463 PyErr_SetString(
5464 PyExc_TypeError,
5465 "spawnvp() arg 2 must contain only strings");
5466 Py_DECREF(opath);
5467 return NULL;
5468 }
5469 }
5470 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005471
Victor Stinner8c62be82010-05-06 00:08:46 +00005472 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005473#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005474 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005475#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005476 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005477#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005478 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005479
Victor Stinner8c62be82010-05-06 00:08:46 +00005480 free_string_array(argvlist, argc);
5481 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005482
Victor Stinner8c62be82010-05-06 00:08:46 +00005483 if (spawnval == -1)
5484 return posix_error();
5485 else
5486 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005487}
5488
5489
5490PyDoc_STRVAR(posix_spawnvpe__doc__,
5491"spawnvpe(mode, file, args, env)\n\n\
5492Execute the program 'file' in a new process, using the environment\n\
5493search path to find the file.\n\
5494\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005495 mode: mode of process creation\n\
5496 file: executable file name\n\
5497 args: tuple or list of arguments\n\
5498 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005499
5500static PyObject *
5501posix_spawnvpe(PyObject *self, PyObject *args)
5502{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005503 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005504 char *path;
5505 PyObject *argv, *env;
5506 char **argvlist;
5507 char **envlist;
5508 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005509 int mode;
5510 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005511 Py_intptr_t spawnval;
5512 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5513 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005514
Victor Stinner8c62be82010-05-06 00:08:46 +00005515 /* spawnvpe has four arguments: (mode, path, argv, env), where
5516 argv is a list or tuple of strings and env is a dictionary
5517 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005518
Victor Stinner8c62be82010-05-06 00:08:46 +00005519 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5520 PyUnicode_FSConverter,
5521 &opath, &argv, &env))
5522 return NULL;
5523 path = PyBytes_AsString(opath);
5524 if (PyList_Check(argv)) {
5525 argc = PyList_Size(argv);
5526 getitem = PyList_GetItem;
5527 }
5528 else if (PyTuple_Check(argv)) {
5529 argc = PyTuple_Size(argv);
5530 getitem = PyTuple_GetItem;
5531 }
5532 else {
5533 PyErr_SetString(PyExc_TypeError,
5534 "spawnvpe() arg 2 must be a tuple or list");
5535 goto fail_0;
5536 }
5537 if (!PyMapping_Check(env)) {
5538 PyErr_SetString(PyExc_TypeError,
5539 "spawnvpe() arg 3 must be a mapping object");
5540 goto fail_0;
5541 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005542
Victor Stinner8c62be82010-05-06 00:08:46 +00005543 argvlist = PyMem_NEW(char *, argc+1);
5544 if (argvlist == NULL) {
5545 PyErr_NoMemory();
5546 goto fail_0;
5547 }
5548 for (i = 0; i < argc; i++) {
5549 if (!fsconvert_strdup((*getitem)(argv, i),
5550 &argvlist[i]))
5551 {
5552 lastarg = i;
5553 goto fail_1;
5554 }
5555 }
5556 lastarg = argc;
5557 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005558
Victor Stinner8c62be82010-05-06 00:08:46 +00005559 envlist = parse_envlist(env, &envc);
5560 if (envlist == NULL)
5561 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005562
Victor Stinner8c62be82010-05-06 00:08:46 +00005563 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005564#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005565 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005566#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005567 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005568#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005569 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005570
Victor Stinner8c62be82010-05-06 00:08:46 +00005571 if (spawnval == -1)
5572 (void) posix_error();
5573 else
5574 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005575
Victor Stinner8c62be82010-05-06 00:08:46 +00005576 while (--envc >= 0)
5577 PyMem_DEL(envlist[envc]);
5578 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005579 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005580 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005581 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 Py_DECREF(opath);
5583 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005584}
5585#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005586#endif /* HAVE_SPAWNV */
5587
5588
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005589#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005590PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005591"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005592Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5593\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005594Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005595
5596static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005597posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005598{
Victor Stinner8c62be82010-05-06 00:08:46 +00005599 pid_t pid;
5600 int result = 0;
5601 _PyImport_AcquireLock();
5602 pid = fork1();
5603 if (pid == 0) {
5604 /* child: this clobbers and resets the import lock. */
5605 PyOS_AfterFork();
5606 } else {
5607 /* parent: release the import lock. */
5608 result = _PyImport_ReleaseLock();
5609 }
5610 if (pid == -1)
5611 return posix_error();
5612 if (result < 0) {
5613 /* Don't clobber the OSError if the fork failed. */
5614 PyErr_SetString(PyExc_RuntimeError,
5615 "not holding the import lock");
5616 return NULL;
5617 }
5618 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005619}
5620#endif
5621
5622
Guido van Rossumad0ee831995-03-01 10:34:45 +00005623#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005624PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005625"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005626Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005627Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005628
Barry Warsaw53699e91996-12-10 23:23:01 +00005629static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005630posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005631{
Victor Stinner8c62be82010-05-06 00:08:46 +00005632 pid_t pid;
5633 int result = 0;
5634 _PyImport_AcquireLock();
5635 pid = fork();
5636 if (pid == 0) {
5637 /* child: this clobbers and resets the import lock. */
5638 PyOS_AfterFork();
5639 } else {
5640 /* parent: release the import lock. */
5641 result = _PyImport_ReleaseLock();
5642 }
5643 if (pid == -1)
5644 return posix_error();
5645 if (result < 0) {
5646 /* Don't clobber the OSError if the fork failed. */
5647 PyErr_SetString(PyExc_RuntimeError,
5648 "not holding the import lock");
5649 return NULL;
5650 }
5651 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005652}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005653#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005654
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005655#ifdef HAVE_SCHED_H
5656
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005657#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5658
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005659PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5660"sched_get_priority_max(policy)\n\n\
5661Get the maximum scheduling priority for *policy*.");
5662
5663static PyObject *
5664posix_sched_get_priority_max(PyObject *self, PyObject *args)
5665{
5666 int policy, max;
5667
5668 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5669 return NULL;
5670 max = sched_get_priority_max(policy);
5671 if (max < 0)
5672 return posix_error();
5673 return PyLong_FromLong(max);
5674}
5675
5676PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5677"sched_get_priority_min(policy)\n\n\
5678Get the minimum scheduling priority for *policy*.");
5679
5680static PyObject *
5681posix_sched_get_priority_min(PyObject *self, PyObject *args)
5682{
5683 int policy, min;
5684
5685 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5686 return NULL;
5687 min = sched_get_priority_min(policy);
5688 if (min < 0)
5689 return posix_error();
5690 return PyLong_FromLong(min);
5691}
5692
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005693#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5694
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005695#ifdef HAVE_SCHED_SETSCHEDULER
5696
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005697PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5698"sched_getscheduler(pid)\n\n\
5699Get the scheduling policy for the process with a PID of *pid*.\n\
5700Passing a PID of 0 returns the scheduling policy for the calling process.");
5701
5702static PyObject *
5703posix_sched_getscheduler(PyObject *self, PyObject *args)
5704{
5705 pid_t pid;
5706 int policy;
5707
5708 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5709 return NULL;
5710 policy = sched_getscheduler(pid);
5711 if (policy < 0)
5712 return posix_error();
5713 return PyLong_FromLong(policy);
5714}
5715
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005716#endif
5717
5718#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5719
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005720static PyObject *
5721sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5722{
5723 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005724 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005725
5726 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5727 return NULL;
5728 res = PyStructSequence_New(type);
5729 if (!res)
5730 return NULL;
5731 Py_INCREF(priority);
5732 PyStructSequence_SET_ITEM(res, 0, priority);
5733 return res;
5734}
5735
5736PyDoc_STRVAR(sched_param__doc__,
5737"sched_param(sched_priority): A scheduling parameter.\n\n\
5738Current has only one field: sched_priority");
5739
5740static PyStructSequence_Field sched_param_fields[] = {
5741 {"sched_priority", "the scheduling priority"},
5742 {0}
5743};
5744
5745static PyStructSequence_Desc sched_param_desc = {
5746 "sched_param", /* name */
5747 sched_param__doc__, /* doc */
5748 sched_param_fields,
5749 1
5750};
5751
5752static int
5753convert_sched_param(PyObject *param, struct sched_param *res)
5754{
5755 long priority;
5756
5757 if (Py_TYPE(param) != &SchedParamType) {
5758 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5759 return 0;
5760 }
5761 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5762 if (priority == -1 && PyErr_Occurred())
5763 return 0;
5764 if (priority > INT_MAX || priority < INT_MIN) {
5765 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5766 return 0;
5767 }
5768 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5769 return 1;
5770}
5771
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005772#endif
5773
5774#ifdef HAVE_SCHED_SETSCHEDULER
5775
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005776PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5777"sched_setscheduler(pid, policy, param)\n\n\
5778Set the scheduling policy, *policy*, for *pid*.\n\
5779If *pid* is 0, the calling process is changed.\n\
5780*param* is an instance of sched_param.");
5781
5782static PyObject *
5783posix_sched_setscheduler(PyObject *self, PyObject *args)
5784{
5785 pid_t pid;
5786 int policy;
5787 struct sched_param param;
5788
5789 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5790 &pid, &policy, &convert_sched_param, &param))
5791 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005792
5793 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005794 ** sched_setscheduler() returns 0 in Linux, but the previous
5795 ** scheduling policy under Solaris/Illumos, and others.
5796 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005797 */
5798 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005799 return posix_error();
5800 Py_RETURN_NONE;
5801}
5802
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005803#endif
5804
5805#ifdef HAVE_SCHED_SETPARAM
5806
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005807PyDoc_STRVAR(posix_sched_getparam__doc__,
5808"sched_getparam(pid) -> sched_param\n\n\
5809Returns scheduling parameters for the process with *pid* as an instance of the\n\
5810sched_param class. A PID of 0 means the calling process.");
5811
5812static PyObject *
5813posix_sched_getparam(PyObject *self, PyObject *args)
5814{
5815 pid_t pid;
5816 struct sched_param param;
5817 PyObject *res, *priority;
5818
5819 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5820 return NULL;
5821 if (sched_getparam(pid, &param))
5822 return posix_error();
5823 res = PyStructSequence_New(&SchedParamType);
5824 if (!res)
5825 return NULL;
5826 priority = PyLong_FromLong(param.sched_priority);
5827 if (!priority) {
5828 Py_DECREF(res);
5829 return NULL;
5830 }
5831 PyStructSequence_SET_ITEM(res, 0, priority);
5832 return res;
5833}
5834
5835PyDoc_STRVAR(posix_sched_setparam__doc__,
5836"sched_setparam(pid, param)\n\n\
5837Set scheduling parameters for a process with PID *pid*.\n\
5838A PID of 0 means the calling process.");
5839
5840static PyObject *
5841posix_sched_setparam(PyObject *self, PyObject *args)
5842{
5843 pid_t pid;
5844 struct sched_param param;
5845
5846 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5847 &pid, &convert_sched_param, &param))
5848 return NULL;
5849 if (sched_setparam(pid, &param))
5850 return posix_error();
5851 Py_RETURN_NONE;
5852}
5853
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005854#endif
5855
5856#ifdef HAVE_SCHED_RR_GET_INTERVAL
5857
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005858PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5859"sched_rr_get_interval(pid) -> float\n\n\
5860Return the round-robin quantum for the process with PID *pid* in seconds.");
5861
5862static PyObject *
5863posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5864{
5865 pid_t pid;
5866 struct timespec interval;
5867
5868 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5869 return NULL;
5870 if (sched_rr_get_interval(pid, &interval))
5871 return posix_error();
5872 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5873}
5874
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005875#endif
5876
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005877PyDoc_STRVAR(posix_sched_yield__doc__,
5878"sched_yield()\n\n\
5879Voluntarily relinquish the CPU.");
5880
5881static PyObject *
5882posix_sched_yield(PyObject *self, PyObject *noargs)
5883{
5884 if (sched_yield())
5885 return posix_error();
5886 Py_RETURN_NONE;
5887}
5888
Benjamin Peterson2740af82011-08-02 17:41:34 -05005889#ifdef HAVE_SCHED_SETAFFINITY
5890
Antoine Pitrou84869872012-08-04 16:16:35 +02005891/* The minimum number of CPUs allocated in a cpu_set_t */
5892static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005893
5894PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5895"sched_setaffinity(pid, cpu_set)\n\n\
5896Set the affinity of the process with PID *pid* to *cpu_set*.");
5897
5898static PyObject *
5899posix_sched_setaffinity(PyObject *self, PyObject *args)
5900{
5901 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005902 int ncpus;
5903 size_t setsize;
5904 cpu_set_t *mask = NULL;
5905 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005906
Antoine Pitrou84869872012-08-04 16:16:35 +02005907 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5908 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005909 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005910
5911 iterator = PyObject_GetIter(iterable);
5912 if (iterator == NULL)
5913 return NULL;
5914
5915 ncpus = NCPUS_START;
5916 setsize = CPU_ALLOC_SIZE(ncpus);
5917 mask = CPU_ALLOC(ncpus);
5918 if (mask == NULL) {
5919 PyErr_NoMemory();
5920 goto error;
5921 }
5922 CPU_ZERO_S(setsize, mask);
5923
5924 while ((item = PyIter_Next(iterator))) {
5925 long cpu;
5926 if (!PyLong_Check(item)) {
5927 PyErr_Format(PyExc_TypeError,
5928 "expected an iterator of ints, "
5929 "but iterator yielded %R",
5930 Py_TYPE(item));
5931 Py_DECREF(item);
5932 goto error;
5933 }
5934 cpu = PyLong_AsLong(item);
5935 Py_DECREF(item);
5936 if (cpu < 0) {
5937 if (!PyErr_Occurred())
5938 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5939 goto error;
5940 }
5941 if (cpu > INT_MAX - 1) {
5942 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5943 goto error;
5944 }
5945 if (cpu >= ncpus) {
5946 /* Grow CPU mask to fit the CPU number */
5947 int newncpus = ncpus;
5948 cpu_set_t *newmask;
5949 size_t newsetsize;
5950 while (newncpus <= cpu) {
5951 if (newncpus > INT_MAX / 2)
5952 newncpus = cpu + 1;
5953 else
5954 newncpus = newncpus * 2;
5955 }
5956 newmask = CPU_ALLOC(newncpus);
5957 if (newmask == NULL) {
5958 PyErr_NoMemory();
5959 goto error;
5960 }
5961 newsetsize = CPU_ALLOC_SIZE(newncpus);
5962 CPU_ZERO_S(newsetsize, newmask);
5963 memcpy(newmask, mask, setsize);
5964 CPU_FREE(mask);
5965 setsize = newsetsize;
5966 mask = newmask;
5967 ncpus = newncpus;
5968 }
5969 CPU_SET_S(cpu, setsize, mask);
5970 }
5971 Py_CLEAR(iterator);
5972
5973 if (sched_setaffinity(pid, setsize, mask)) {
5974 posix_error();
5975 goto error;
5976 }
5977 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005978 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005979
5980error:
5981 if (mask)
5982 CPU_FREE(mask);
5983 Py_XDECREF(iterator);
5984 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005985}
5986
5987PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5988"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5989Return the affinity of the process with PID *pid*.\n\
5990The returned cpu_set will be of size *ncpus*.");
5991
5992static PyObject *
5993posix_sched_getaffinity(PyObject *self, PyObject *args)
5994{
5995 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005996 int cpu, ncpus, count;
5997 size_t setsize;
5998 cpu_set_t *mask = NULL;
5999 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006000
Antoine Pitrou84869872012-08-04 16:16:35 +02006001 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
6002 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006003 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02006004
6005 ncpus = NCPUS_START;
6006 while (1) {
6007 setsize = CPU_ALLOC_SIZE(ncpus);
6008 mask = CPU_ALLOC(ncpus);
6009 if (mask == NULL)
6010 return PyErr_NoMemory();
6011 if (sched_getaffinity(pid, setsize, mask) == 0)
6012 break;
6013 CPU_FREE(mask);
6014 if (errno != EINVAL)
6015 return posix_error();
6016 if (ncpus > INT_MAX / 2) {
6017 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6018 "a large enough CPU set");
6019 return NULL;
6020 }
6021 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006022 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006023
6024 res = PySet_New(NULL);
6025 if (res == NULL)
6026 goto error;
6027 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6028 if (CPU_ISSET_S(cpu, setsize, mask)) {
6029 PyObject *cpu_num = PyLong_FromLong(cpu);
6030 --count;
6031 if (cpu_num == NULL)
6032 goto error;
6033 if (PySet_Add(res, cpu_num)) {
6034 Py_DECREF(cpu_num);
6035 goto error;
6036 }
6037 Py_DECREF(cpu_num);
6038 }
6039 }
6040 CPU_FREE(mask);
6041 return res;
6042
6043error:
6044 if (mask)
6045 CPU_FREE(mask);
6046 Py_XDECREF(res);
6047 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006048}
6049
Benjamin Peterson2740af82011-08-02 17:41:34 -05006050#endif /* HAVE_SCHED_SETAFFINITY */
6051
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006052#endif /* HAVE_SCHED_H */
6053
Neal Norwitzb59798b2003-03-21 01:43:31 +00006054/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006055/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6056#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006057#define DEV_PTY_FILE "/dev/ptc"
6058#define HAVE_DEV_PTMX
6059#else
6060#define DEV_PTY_FILE "/dev/ptmx"
6061#endif
6062
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006063#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006064#ifdef HAVE_PTY_H
6065#include <pty.h>
6066#else
6067#ifdef HAVE_LIBUTIL_H
6068#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006069#else
6070#ifdef HAVE_UTIL_H
6071#include <util.h>
6072#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006073#endif /* HAVE_LIBUTIL_H */
6074#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006075#ifdef HAVE_STROPTS_H
6076#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006077#endif
6078#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006079
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006080#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006082"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006083Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006084
6085static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006086posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006087{
Victor Stinner8c62be82010-05-06 00:08:46 +00006088 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006089#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006090 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006091#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006092#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006094#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006095 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006096#endif
6097#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006098
Thomas Wouters70c21a12000-07-14 14:28:33 +00006099#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006100 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6101 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006102#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006103 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6104 if (slave_name == NULL)
6105 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006106
Victor Stinner8c62be82010-05-06 00:08:46 +00006107 slave_fd = open(slave_name, O_RDWR);
6108 if (slave_fd < 0)
6109 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006110#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6112 if (master_fd < 0)
6113 return posix_error();
6114 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6115 /* change permission of slave */
6116 if (grantpt(master_fd) < 0) {
6117 PyOS_setsig(SIGCHLD, sig_saved);
6118 return posix_error();
6119 }
6120 /* unlock slave */
6121 if (unlockpt(master_fd) < 0) {
6122 PyOS_setsig(SIGCHLD, sig_saved);
6123 return posix_error();
6124 }
6125 PyOS_setsig(SIGCHLD, sig_saved);
6126 slave_name = ptsname(master_fd); /* get name of slave */
6127 if (slave_name == NULL)
6128 return posix_error();
6129 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6130 if (slave_fd < 0)
6131 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006132#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006133 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6134 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006135#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006136 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006137#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006138#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006139#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006140
Victor Stinner8c62be82010-05-06 00:08:46 +00006141 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006142
Fred Drake8cef4cf2000-06-28 16:40:38 +00006143}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006144#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006145
6146#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006147PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006148"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006149Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6150Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006152
6153static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006154posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006155{
Victor Stinner8c62be82010-05-06 00:08:46 +00006156 int master_fd = -1, result = 0;
6157 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006158
Victor Stinner8c62be82010-05-06 00:08:46 +00006159 _PyImport_AcquireLock();
6160 pid = forkpty(&master_fd, NULL, NULL, NULL);
6161 if (pid == 0) {
6162 /* child: this clobbers and resets the import lock. */
6163 PyOS_AfterFork();
6164 } else {
6165 /* parent: release the import lock. */
6166 result = _PyImport_ReleaseLock();
6167 }
6168 if (pid == -1)
6169 return posix_error();
6170 if (result < 0) {
6171 /* Don't clobber the OSError if the fork failed. */
6172 PyErr_SetString(PyExc_RuntimeError,
6173 "not holding the import lock");
6174 return NULL;
6175 }
6176 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006177}
6178#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006179
Ross Lagerwall7807c352011-03-17 20:20:30 +02006180
Guido van Rossumad0ee831995-03-01 10:34:45 +00006181#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006182PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006183"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006184Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006185
Barry Warsaw53699e91996-12-10 23:23:01 +00006186static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006187posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006188{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006189 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006190}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006191#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Guido van Rossumad0ee831995-03-01 10:34:45 +00006194#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006195PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006196"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006197Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006198
Barry Warsaw53699e91996-12-10 23:23:01 +00006199static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006200posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006201{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006202 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006203}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006204#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006205
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006206
Guido van Rossumad0ee831995-03-01 10:34:45 +00006207#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006208PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006209"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006210Return the current process's group 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_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006214{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006215 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006216}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006217#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006218
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006219
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006220PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006221"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006222Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006223
Barry Warsaw53699e91996-12-10 23:23:01 +00006224static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006225posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006226{
Victor Stinner8c62be82010-05-06 00:08:46 +00006227 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006228}
6229
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006230#ifdef HAVE_GETGROUPLIST
6231PyDoc_STRVAR(posix_getgrouplist__doc__,
6232"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6233Returns a list of groups to which a user belongs.\n\n\
6234 user: username to lookup\n\
6235 group: base group id of the user");
6236
6237static PyObject *
6238posix_getgrouplist(PyObject *self, PyObject *args)
6239{
6240#ifdef NGROUPS_MAX
6241#define MAX_GROUPS NGROUPS_MAX
6242#else
6243 /* defined to be 16 on Solaris7, so this should be a small number */
6244#define MAX_GROUPS 64
6245#endif
6246
6247 const char *user;
6248 int i, ngroups;
6249 PyObject *list;
6250#ifdef __APPLE__
6251 int *groups, basegid;
6252#else
6253 gid_t *groups, basegid;
6254#endif
6255 ngroups = MAX_GROUPS;
6256
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006257#ifdef __APPLE__
6258 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006259 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006260#else
6261 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6262 _Py_Gid_Converter, &basegid))
6263 return NULL;
6264#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006265
6266#ifdef __APPLE__
6267 groups = PyMem_Malloc(ngroups * sizeof(int));
6268#else
6269 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6270#endif
6271 if (groups == NULL)
6272 return PyErr_NoMemory();
6273
6274 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6275 PyMem_Del(groups);
6276 return posix_error();
6277 }
6278
6279 list = PyList_New(ngroups);
6280 if (list == NULL) {
6281 PyMem_Del(groups);
6282 return NULL;
6283 }
6284
6285 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006286#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006287 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006288#else
6289 PyObject *o = _PyLong_FromGid(groups[i]);
6290#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006291 if (o == NULL) {
6292 Py_DECREF(list);
6293 PyMem_Del(groups);
6294 return NULL;
6295 }
6296 PyList_SET_ITEM(list, i, o);
6297 }
6298
6299 PyMem_Del(groups);
6300
6301 return list;
6302}
6303#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006304
Fred Drakec9680921999-12-13 16:37:25 +00006305#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006306PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006307"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006308Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006309
6310static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006311posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006312{
6313 PyObject *result = NULL;
6314
Fred Drakec9680921999-12-13 16:37:25 +00006315#ifdef NGROUPS_MAX
6316#define MAX_GROUPS NGROUPS_MAX
6317#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006318 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006319#define MAX_GROUPS 64
6320#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006322
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006323 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006324 * This is a helper variable to store the intermediate result when
6325 * that happens.
6326 *
6327 * To keep the code readable the OSX behaviour is unconditional,
6328 * according to the POSIX spec this should be safe on all unix-y
6329 * systems.
6330 */
6331 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006333
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006334#ifdef __APPLE__
6335 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6336 * there are more groups than can fit in grouplist. Therefore, on OS X
6337 * always first call getgroups with length 0 to get the actual number
6338 * of groups.
6339 */
6340 n = getgroups(0, NULL);
6341 if (n < 0) {
6342 return posix_error();
6343 } else if (n <= MAX_GROUPS) {
6344 /* groups will fit in existing array */
6345 alt_grouplist = grouplist;
6346 } else {
6347 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6348 if (alt_grouplist == NULL) {
6349 errno = EINVAL;
6350 return posix_error();
6351 }
6352 }
6353
6354 n = getgroups(n, alt_grouplist);
6355 if (n == -1) {
6356 if (alt_grouplist != grouplist) {
6357 PyMem_Free(alt_grouplist);
6358 }
6359 return posix_error();
6360 }
6361#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006363 if (n < 0) {
6364 if (errno == EINVAL) {
6365 n = getgroups(0, NULL);
6366 if (n == -1) {
6367 return posix_error();
6368 }
6369 if (n == 0) {
6370 /* Avoid malloc(0) */
6371 alt_grouplist = grouplist;
6372 } else {
6373 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6374 if (alt_grouplist == NULL) {
6375 errno = EINVAL;
6376 return posix_error();
6377 }
6378 n = getgroups(n, alt_grouplist);
6379 if (n == -1) {
6380 PyMem_Free(alt_grouplist);
6381 return posix_error();
6382 }
6383 }
6384 } else {
6385 return posix_error();
6386 }
6387 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006388#endif
6389
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006390 result = PyList_New(n);
6391 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 int i;
6393 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006394 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006396 Py_DECREF(result);
6397 result = NULL;
6398 break;
Fred Drakec9680921999-12-13 16:37:25 +00006399 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006401 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006402 }
6403
6404 if (alt_grouplist != grouplist) {
6405 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006406 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006407
Fred Drakec9680921999-12-13 16:37:25 +00006408 return result;
6409}
6410#endif
6411
Antoine Pitroub7572f02009-12-02 20:46:48 +00006412#ifdef HAVE_INITGROUPS
6413PyDoc_STRVAR(posix_initgroups__doc__,
6414"initgroups(username, gid) -> None\n\n\
6415Call the system initgroups() to initialize the group access list with all of\n\
6416the groups of which the specified username is a member, plus the specified\n\
6417group id.");
6418
6419static PyObject *
6420posix_initgroups(PyObject *self, PyObject *args)
6421{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006422 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006424 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006425#ifdef __APPLE__
6426 int gid;
6427#else
6428 gid_t gid;
6429#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006430
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006431#ifdef __APPLE__
6432 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6433 PyUnicode_FSConverter, &oname,
6434 &gid))
6435#else
6436 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6437 PyUnicode_FSConverter, &oname,
6438 _Py_Gid_Converter, &gid))
6439#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006441 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006442
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006443 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006444 Py_DECREF(oname);
6445 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006447
Victor Stinner8c62be82010-05-06 00:08:46 +00006448 Py_INCREF(Py_None);
6449 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006450}
6451#endif
6452
Martin v. Löwis606edc12002-06-13 21:09:11 +00006453#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006454PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006455"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006456Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006457
6458static PyObject *
6459posix_getpgid(PyObject *self, PyObject *args)
6460{
Victor Stinner8c62be82010-05-06 00:08:46 +00006461 pid_t pid, pgid;
6462 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6463 return NULL;
6464 pgid = getpgid(pid);
6465 if (pgid < 0)
6466 return posix_error();
6467 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006468}
6469#endif /* HAVE_GETPGID */
6470
6471
Guido van Rossumb6775db1994-08-01 11:34:53 +00006472#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006473PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006474"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006475Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006476
Barry Warsaw53699e91996-12-10 23:23:01 +00006477static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006478posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006479{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006480#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006482#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006483 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006484#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006485}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006486#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006487
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006488
Guido van Rossumb6775db1994-08-01 11:34:53 +00006489#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006491"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006492Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006493
Barry Warsaw53699e91996-12-10 23:23:01 +00006494static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006495posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006496{
Guido van Rossum64933891994-10-20 21:56:42 +00006497#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006498 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006499#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006501#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 return posix_error();
6503 Py_INCREF(Py_None);
6504 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006505}
6506
Guido van Rossumb6775db1994-08-01 11:34:53 +00006507#endif /* HAVE_SETPGRP */
6508
Guido van Rossumad0ee831995-03-01 10:34:45 +00006509#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006510
6511#ifdef MS_WINDOWS
6512#include <tlhelp32.h>
6513
6514static PyObject*
6515win32_getppid()
6516{
6517 HANDLE snapshot;
6518 pid_t mypid;
6519 PyObject* result = NULL;
6520 BOOL have_record;
6521 PROCESSENTRY32 pe;
6522
6523 mypid = getpid(); /* This function never fails */
6524
6525 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6526 if (snapshot == INVALID_HANDLE_VALUE)
6527 return PyErr_SetFromWindowsErr(GetLastError());
6528
6529 pe.dwSize = sizeof(pe);
6530 have_record = Process32First(snapshot, &pe);
6531 while (have_record) {
6532 if (mypid == (pid_t)pe.th32ProcessID) {
6533 /* We could cache the ulong value in a static variable. */
6534 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6535 break;
6536 }
6537
6538 have_record = Process32Next(snapshot, &pe);
6539 }
6540
6541 /* If our loop exits and our pid was not found (result will be NULL)
6542 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6543 * error anyway, so let's raise it. */
6544 if (!result)
6545 result = PyErr_SetFromWindowsErr(GetLastError());
6546
6547 CloseHandle(snapshot);
6548
6549 return result;
6550}
6551#endif /*MS_WINDOWS*/
6552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006554"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006555Return the parent's process id. If the parent process has already exited,\n\
6556Windows machines will still return its id; others systems will return the id\n\
6557of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006558
Barry Warsaw53699e91996-12-10 23:23:01 +00006559static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006560posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006561{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006562#ifdef MS_WINDOWS
6563 return win32_getppid();
6564#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006566#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006567}
6568#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006570
Fred Drake12c6e2d1999-12-14 21:25:03 +00006571#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006572PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006573"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006574Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006575
6576static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006577posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006578{
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006580#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006581 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006582 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006583
6584 if (GetUserNameW(user_name, &num_chars)) {
6585 /* num_chars is the number of unicode chars plus null terminator */
6586 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006587 }
6588 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006589 result = PyErr_SetFromWindowsErr(GetLastError());
6590#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 char *name;
6592 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006593
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 errno = 0;
6595 name = getlogin();
6596 if (name == NULL) {
6597 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006598 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006599 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006600 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 }
6602 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006603 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006605#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006606 return result;
6607}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006608#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006609
Guido van Rossumad0ee831995-03-01 10:34:45 +00006610#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006611PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006612"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006613Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006614
Barry Warsaw53699e91996-12-10 23:23:01 +00006615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006616posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006617{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006618 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006619}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006620#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006622
Guido van Rossumad0ee831995-03-01 10:34:45 +00006623#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006624PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006625"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006626Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006627
Barry Warsaw53699e91996-12-10 23:23:01 +00006628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006629posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006630{
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 pid_t pid;
6632 int sig;
6633 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6634 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006635#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006636 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6637 APIRET rc;
6638 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006639 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006640
6641 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6642 APIRET rc;
6643 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006644 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006645
6646 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006647 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006648#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 if (kill(pid, sig) == -1)
6650 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006651#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 Py_INCREF(Py_None);
6653 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006654}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006655#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006656
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006657#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006658PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006659"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006660Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006661
6662static PyObject *
6663posix_killpg(PyObject *self, PyObject *args)
6664{
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 int sig;
6666 pid_t pgid;
6667 /* XXX some man pages make the `pgid` parameter an int, others
6668 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6669 take the same type. Moreover, pid_t is always at least as wide as
6670 int (else compilation of this module fails), which is safe. */
6671 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6672 return NULL;
6673 if (killpg(pgid, sig) == -1)
6674 return posix_error();
6675 Py_INCREF(Py_None);
6676 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006677}
6678#endif
6679
Brian Curtineb24d742010-04-12 17:16:38 +00006680#ifdef MS_WINDOWS
6681PyDoc_STRVAR(win32_kill__doc__,
6682"kill(pid, sig)\n\n\
6683Kill a process with a signal.");
6684
6685static PyObject *
6686win32_kill(PyObject *self, PyObject *args)
6687{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006688 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 DWORD pid, sig, err;
6690 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006691
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6693 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006694
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 /* Console processes which share a common console can be sent CTRL+C or
6696 CTRL+BREAK events, provided they handle said events. */
6697 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6698 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6699 err = GetLastError();
6700 PyErr_SetFromWindowsErr(err);
6701 }
6702 else
6703 Py_RETURN_NONE;
6704 }
Brian Curtineb24d742010-04-12 17:16:38 +00006705
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6707 attempt to open and terminate the process. */
6708 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6709 if (handle == NULL) {
6710 err = GetLastError();
6711 return PyErr_SetFromWindowsErr(err);
6712 }
Brian Curtineb24d742010-04-12 17:16:38 +00006713
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 if (TerminateProcess(handle, sig) == 0) {
6715 err = GetLastError();
6716 result = PyErr_SetFromWindowsErr(err);
6717 } else {
6718 Py_INCREF(Py_None);
6719 result = Py_None;
6720 }
Brian Curtineb24d742010-04-12 17:16:38 +00006721
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 CloseHandle(handle);
6723 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006724}
6725#endif /* MS_WINDOWS */
6726
Guido van Rossumc0125471996-06-28 18:55:32 +00006727#ifdef HAVE_PLOCK
6728
6729#ifdef HAVE_SYS_LOCK_H
6730#include <sys/lock.h>
6731#endif
6732
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006733PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006734"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006735Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006736
Barry Warsaw53699e91996-12-10 23:23:01 +00006737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006738posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006739{
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 int op;
6741 if (!PyArg_ParseTuple(args, "i:plock", &op))
6742 return NULL;
6743 if (plock(op) == -1)
6744 return posix_error();
6745 Py_INCREF(Py_None);
6746 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006747}
6748#endif
6749
Guido van Rossumb6775db1994-08-01 11:34:53 +00006750#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006751PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006752"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006753Set the current process's user id.");
6754
Barry Warsaw53699e91996-12-10 23:23:01 +00006755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006756posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006757{
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006759 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 if (setuid(uid) < 0)
6762 return posix_error();
6763 Py_INCREF(Py_None);
6764 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006765}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006766#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006768
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006769#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006770PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006771"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006772Set the current process's effective user id.");
6773
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006774static PyObject *
6775posix_seteuid (PyObject *self, PyObject *args)
6776{
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006778 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 if (seteuid(euid) < 0) {
6781 return posix_error();
6782 } else {
6783 Py_INCREF(Py_None);
6784 return Py_None;
6785 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006786}
6787#endif /* HAVE_SETEUID */
6788
6789#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006790PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006791"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006792Set the current process's effective group id.");
6793
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006794static PyObject *
6795posix_setegid (PyObject *self, PyObject *args)
6796{
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006798 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 if (setegid(egid) < 0) {
6801 return posix_error();
6802 } else {
6803 Py_INCREF(Py_None);
6804 return Py_None;
6805 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006806}
6807#endif /* HAVE_SETEGID */
6808
6809#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006810PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006811"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812Set the current process's real and effective user ids.");
6813
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006814static PyObject *
6815posix_setreuid (PyObject *self, PyObject *args)
6816{
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006818 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6819 _Py_Uid_Converter, &ruid,
6820 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 if (setreuid(ruid, euid) < 0) {
6823 return posix_error();
6824 } else {
6825 Py_INCREF(Py_None);
6826 return Py_None;
6827 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006828}
6829#endif /* HAVE_SETREUID */
6830
6831#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006833"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006834Set the current process's real and effective group ids.");
6835
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006836static PyObject *
6837posix_setregid (PyObject *self, PyObject *args)
6838{
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006840 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6841 _Py_Gid_Converter, &rgid,
6842 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 if (setregid(rgid, egid) < 0) {
6845 return posix_error();
6846 } else {
6847 Py_INCREF(Py_None);
6848 return Py_None;
6849 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006850}
6851#endif /* HAVE_SETREGID */
6852
Guido van Rossumb6775db1994-08-01 11:34:53 +00006853#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006854PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006855"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006856Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006857
Barry Warsaw53699e91996-12-10 23:23:01 +00006858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006859posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006860{
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006862 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 if (setgid(gid) < 0)
6865 return posix_error();
6866 Py_INCREF(Py_None);
6867 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006868}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006869#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006870
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006871#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006872PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006873"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006874Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006875
6876static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006877posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006878{
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 int i, len;
6880 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006881
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 if (!PySequence_Check(groups)) {
6883 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6884 return NULL;
6885 }
6886 len = PySequence_Size(groups);
6887 if (len > MAX_GROUPS) {
6888 PyErr_SetString(PyExc_ValueError, "too many groups");
6889 return NULL;
6890 }
6891 for(i = 0; i < len; i++) {
6892 PyObject *elem;
6893 elem = PySequence_GetItem(groups, i);
6894 if (!elem)
6895 return NULL;
6896 if (!PyLong_Check(elem)) {
6897 PyErr_SetString(PyExc_TypeError,
6898 "groups must be integers");
6899 Py_DECREF(elem);
6900 return NULL;
6901 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006902 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 Py_DECREF(elem);
6904 return NULL;
6905 }
6906 }
6907 Py_DECREF(elem);
6908 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006909
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 if (setgroups(len, grouplist) < 0)
6911 return posix_error();
6912 Py_INCREF(Py_None);
6913 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006914}
6915#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006916
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6918static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006919wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920{
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 PyObject *result;
6922 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006923 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006924
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 if (pid == -1)
6926 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006927
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 if (struct_rusage == NULL) {
6929 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6930 if (m == NULL)
6931 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006932 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006933 Py_DECREF(m);
6934 if (struct_rusage == NULL)
6935 return NULL;
6936 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006937
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6939 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6940 if (!result)
6941 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006942
6943#ifndef doubletime
6944#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6945#endif
6946
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006948 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006950 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006951#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6953 SET_INT(result, 2, ru->ru_maxrss);
6954 SET_INT(result, 3, ru->ru_ixrss);
6955 SET_INT(result, 4, ru->ru_idrss);
6956 SET_INT(result, 5, ru->ru_isrss);
6957 SET_INT(result, 6, ru->ru_minflt);
6958 SET_INT(result, 7, ru->ru_majflt);
6959 SET_INT(result, 8, ru->ru_nswap);
6960 SET_INT(result, 9, ru->ru_inblock);
6961 SET_INT(result, 10, ru->ru_oublock);
6962 SET_INT(result, 11, ru->ru_msgsnd);
6963 SET_INT(result, 12, ru->ru_msgrcv);
6964 SET_INT(result, 13, ru->ru_nsignals);
6965 SET_INT(result, 14, ru->ru_nvcsw);
6966 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006967#undef SET_INT
6968
Victor Stinner8c62be82010-05-06 00:08:46 +00006969 if (PyErr_Occurred()) {
6970 Py_DECREF(result);
6971 return NULL;
6972 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006973
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006975}
6976#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6977
6978#ifdef HAVE_WAIT3
6979PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006980"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006981Wait for completion of a child process.");
6982
6983static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006984posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006985{
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 pid_t pid;
6987 int options;
6988 struct rusage ru;
6989 WAIT_TYPE status;
6990 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006991
Victor Stinner4195b5c2012-02-08 23:03:19 +01006992 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006993 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006994
Victor Stinner8c62be82010-05-06 00:08:46 +00006995 Py_BEGIN_ALLOW_THREADS
6996 pid = wait3(&status, options, &ru);
6997 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006998
Victor Stinner4195b5c2012-02-08 23:03:19 +01006999 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007000}
7001#endif /* HAVE_WAIT3 */
7002
7003#ifdef HAVE_WAIT4
7004PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01007005"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007006Wait for completion of a given child process.");
7007
7008static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01007009posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007010{
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 pid_t pid;
7012 int options;
7013 struct rusage ru;
7014 WAIT_TYPE status;
7015 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007016
Victor Stinner4195b5c2012-02-08 23:03:19 +01007017 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007019
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 Py_BEGIN_ALLOW_THREADS
7021 pid = wait4(pid, &status, options, &ru);
7022 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007023
Victor Stinner4195b5c2012-02-08 23:03:19 +01007024 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007025}
7026#endif /* HAVE_WAIT4 */
7027
Ross Lagerwall7807c352011-03-17 20:20:30 +02007028#if defined(HAVE_WAITID) && !defined(__APPLE__)
7029PyDoc_STRVAR(posix_waitid__doc__,
7030"waitid(idtype, id, options) -> waitid_result\n\n\
7031Wait for the completion of one or more child processes.\n\n\
7032idtype can be P_PID, P_PGID or P_ALL.\n\
7033id specifies the pid to wait on.\n\
7034options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
7035or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
7036Returns either waitid_result or None if WNOHANG is specified and there are\n\
7037no children in a waitable state.");
7038
7039static PyObject *
7040posix_waitid(PyObject *self, PyObject *args)
7041{
7042 PyObject *result;
7043 idtype_t idtype;
7044 id_t id;
7045 int options, res;
7046 siginfo_t si;
7047 si.si_pid = 0;
7048 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7049 return NULL;
7050 Py_BEGIN_ALLOW_THREADS
7051 res = waitid(idtype, id, &si, options);
7052 Py_END_ALLOW_THREADS
7053 if (res == -1)
7054 return posix_error();
7055
7056 if (si.si_pid == 0)
7057 Py_RETURN_NONE;
7058
7059 result = PyStructSequence_New(&WaitidResultType);
7060 if (!result)
7061 return NULL;
7062
7063 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007064 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007065 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7066 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7067 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7068 if (PyErr_Occurred()) {
7069 Py_DECREF(result);
7070 return NULL;
7071 }
7072
7073 return result;
7074}
7075#endif
7076
Guido van Rossumb6775db1994-08-01 11:34:53 +00007077#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007078PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007079"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007080Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007081
Barry Warsaw53699e91996-12-10 23:23:01 +00007082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007083posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007084{
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 pid_t pid;
7086 int options;
7087 WAIT_TYPE status;
7088 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007089
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7091 return NULL;
7092 Py_BEGIN_ALLOW_THREADS
7093 pid = waitpid(pid, &status, options);
7094 Py_END_ALLOW_THREADS
7095 if (pid == -1)
7096 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007097
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007099}
7100
Tim Petersab034fa2002-02-01 11:27:43 +00007101#elif defined(HAVE_CWAIT)
7102
7103/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007104PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007105"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007106"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007107
7108static PyObject *
7109posix_waitpid(PyObject *self, PyObject *args)
7110{
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 Py_intptr_t pid;
7112 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007113
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7115 return NULL;
7116 Py_BEGIN_ALLOW_THREADS
7117 pid = _cwait(&status, pid, options);
7118 Py_END_ALLOW_THREADS
7119 if (pid == -1)
7120 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007121
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 /* shift the status left a byte so this is more like the POSIX waitpid */
7123 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007124}
7125#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007126
Guido van Rossumad0ee831995-03-01 10:34:45 +00007127#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007128PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007129"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007130Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007131
Barry Warsaw53699e91996-12-10 23:23:01 +00007132static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007133posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007134{
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 pid_t pid;
7136 WAIT_TYPE status;
7137 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007138
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 Py_BEGIN_ALLOW_THREADS
7140 pid = wait(&status);
7141 Py_END_ALLOW_THREADS
7142 if (pid == -1)
7143 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007144
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007146}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007147#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007148
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007149
Larry Hastings9cf065c2012-06-22 16:30:09 -07007150#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7151PyDoc_STRVAR(readlink__doc__,
7152"readlink(path, *, dir_fd=None) -> path\n\n\
7153Return a string representing the path to which the symbolic link points.\n\
7154\n\
7155If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7156 and path should be relative; path will then be relative to that directory.\n\
7157dir_fd may not be implemented on your platform.\n\
7158 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007159#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007160
Guido van Rossumb6775db1994-08-01 11:34:53 +00007161#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007162
Barry Warsaw53699e91996-12-10 23:23:01 +00007163static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007165{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007166 path_t path;
7167 int dir_fd = DEFAULT_DIR_FD;
7168 char buffer[MAXPATHLEN];
7169 ssize_t length;
7170 PyObject *return_value = NULL;
7171 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007172
Larry Hastings9cf065c2012-06-22 16:30:09 -07007173 memset(&path, 0, sizeof(path));
7174 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7175 path_converter, &path,
7176#ifdef HAVE_READLINKAT
7177 dir_fd_converter, &dir_fd
7178#else
7179 dir_fd_unavailable, &dir_fd
7180#endif
7181 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007182 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007183
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007185#ifdef HAVE_READLINKAT
7186 if (dir_fd != DEFAULT_DIR_FD)
7187 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007188 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007189#endif
7190 length = readlink(path.narrow, buffer, sizeof(buffer));
7191 Py_END_ALLOW_THREADS
7192
7193 if (length < 0) {
7194 return_value = path_posix_error("readlink", &path);
7195 goto exit;
7196 }
7197
7198 if (PyUnicode_Check(path.object))
7199 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7200 else
7201 return_value = PyBytes_FromStringAndSize(buffer, length);
7202exit:
7203 path_cleanup(&path);
7204 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007205}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007206
7207
Guido van Rossumb6775db1994-08-01 11:34:53 +00007208#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007210
Larry Hastings9cf065c2012-06-22 16:30:09 -07007211#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007212PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007213"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7214Create a symbolic link pointing to src named dst.\n\n\
7215target_is_directory is required on Windows if the target is to be\n\
7216 interpreted as a directory. (On Windows, symlink requires\n\
7217 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7218 target_is_directory is ignored on non-Windows platforms.\n\
7219\n\
7220If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7221 and path should be relative; path will then be relative to that directory.\n\
7222dir_fd may not be implemented on your platform.\n\
7223 If it is unavailable, using it will raise a NotImplementedError.");
7224
7225#if defined(MS_WINDOWS)
7226
7227/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7228static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7229static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7230static int
7231check_CreateSymbolicLink()
7232{
7233 HINSTANCE hKernel32;
7234 /* only recheck */
7235 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7236 return 1;
7237 hKernel32 = GetModuleHandleW(L"KERNEL32");
7238 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7239 "CreateSymbolicLinkW");
7240 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7241 "CreateSymbolicLinkA");
7242 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7243}
7244
Jason R. Coombs3a092862013-05-27 23:21:28 -04007245void _dirnameW(WCHAR *path) {
7246 /* Remove the last portion of the path */
7247
7248 WCHAR *ptr;
7249
7250 /* walk the path from the end until a backslash is encountered */
7251 for(ptr = path + wcslen(path); ptr != path; ptr--)
7252 {
7253 if(*ptr == *L"\\" || *ptr == *L"/") {
7254 break;
7255 }
7256 }
7257 *ptr = 0;
7258}
7259
7260void _dirnameA(char *path) {
7261 /* Remove the last portion of the path */
7262
7263 char *ptr;
7264
7265 /* walk the path from the end until a backslash is encountered */
7266 for(ptr = path + strlen(path); ptr != path; ptr--)
7267 {
7268 if(*ptr == '\\' || *ptr == '/') {
7269 break;
7270 }
7271 }
7272 *ptr = 0;
7273}
7274
7275int _is_absW(WCHAR *path) {
7276 /* Is this path absolute? */
7277
7278 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7279
7280}
7281
7282int _is_absA(char *path) {
7283 /* Is this path absolute? */
7284
7285 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7286
7287}
7288
7289void _joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) {
7290 /* join root and rest with a backslash */
7291 int root_len;
7292
7293 if(_is_absW(rest)) {
7294 wcscpy(dest_path, rest);
7295 return;
7296 }
7297
7298 root_len = wcslen(root);
7299
7300 wcscpy(dest_path, root);
7301 if(root_len) {
7302 dest_path[root_len] = *L"\\";
7303 root_len += 1;
7304 }
7305 wcscpy(dest_path+root_len, rest);
7306}
7307
7308void _joinA(char *dest_path, const char *root, const char *rest) {
7309 /* join root and rest with a backslash */
7310 int root_len;
7311
7312 if(_is_absA(rest)) {
7313 strcpy(dest_path, rest);
7314 return;
7315 }
7316
7317 root_len = strlen(root);
7318
7319 strcpy(dest_path, root);
7320 if(root_len) {
7321 dest_path[root_len] = '\\';
7322 root_len += 1;
7323 }
7324 strcpy(dest_path+root_len, rest);
7325}
7326
7327int _check_dirW(WCHAR *src, WCHAR *dest)
7328{
7329 /* Return True if the path at src relative to dest is a directory */
7330 WIN32_FILE_ATTRIBUTE_DATA src_info;
7331 WCHAR dest_parent[MAX_PATH];
7332 WCHAR src_resolved[MAX_PATH] = L"";
7333
7334 /* dest_parent = os.path.dirname(dest) */
7335 wcscpy(dest_parent, dest);
7336 _dirnameW(dest_parent);
7337 /* src_resolved = os.path.join(dest_parent, src) */
7338 _joinW(src_resolved, dest_parent, src);
7339 return (
7340 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7341 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7342 );
7343}
7344
7345int _check_dirA(char *src, char *dest)
7346{
7347 /* Return True if the path at src relative to dest is a directory */
7348 WIN32_FILE_ATTRIBUTE_DATA src_info;
7349 char dest_parent[MAX_PATH];
7350 char src_resolved[MAX_PATH] = "";
7351
7352 /* dest_parent = os.path.dirname(dest) */
7353 strcpy(dest_parent, dest);
7354 _dirnameW(dest_parent);
7355 /* src_resolved = os.path.join(dest_parent, src) */
7356 _joinW(src_resolved, dest_parent, src);
7357 return (
7358 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7359 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7360 );
7361}
7362
Larry Hastings9cf065c2012-06-22 16:30:09 -07007363#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007364
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007365static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007366posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007367{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007368 path_t src;
7369 path_t dst;
7370 int dir_fd = DEFAULT_DIR_FD;
7371 int target_is_directory = 0;
7372 static char *keywords[] = {"src", "dst", "target_is_directory",
7373 "dir_fd", NULL};
7374 PyObject *return_value;
7375#ifdef MS_WINDOWS
7376 DWORD result;
7377#else
7378 int result;
7379#endif
7380
7381 memset(&src, 0, sizeof(src));
7382 src.argument_name = "src";
7383 memset(&dst, 0, sizeof(dst));
7384 dst.argument_name = "dst";
7385
7386#ifdef MS_WINDOWS
7387 if (!check_CreateSymbolicLink()) {
7388 PyErr_SetString(PyExc_NotImplementedError,
7389 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007390 return NULL;
7391 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392 if (!win32_can_symlink) {
7393 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007394 return NULL;
7395 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396#endif
7397
7398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7399 keywords,
7400 path_converter, &src,
7401 path_converter, &dst,
7402 &target_is_directory,
7403#ifdef HAVE_SYMLINKAT
7404 dir_fd_converter, &dir_fd
7405#else
7406 dir_fd_unavailable, &dir_fd
7407#endif
7408 ))
7409 return NULL;
7410
7411 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7412 PyErr_SetString(PyExc_ValueError,
7413 "symlink: src and dst must be the same type");
7414 return_value = NULL;
7415 goto exit;
7416 }
7417
7418#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007419
Larry Hastings9cf065c2012-06-22 16:30:09 -07007420 Py_BEGIN_ALLOW_THREADS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007421 if (dst.wide) {
7422 /* if src is a directory, ensure target_is_directory==1 */
7423 target_is_directory |= _check_dirW(src.wide, dst.wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007424 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7425 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007426 }
7427 else {
7428 /* if src is a directory, ensure target_is_directory==1 */
7429 target_is_directory |= _check_dirA(src.narrow, dst.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7431 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007432 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007433 Py_END_ALLOW_THREADS
7434
7435 if (!result) {
7436 return_value = win32_error_object("symlink", src.object);
7437 goto exit;
7438 }
7439
7440#else
7441
7442 Py_BEGIN_ALLOW_THREADS
7443#if HAVE_SYMLINKAT
7444 if (dir_fd != DEFAULT_DIR_FD)
7445 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7446 else
7447#endif
7448 result = symlink(src.narrow, dst.narrow);
7449 Py_END_ALLOW_THREADS
7450
7451 if (result) {
7452 return_value = path_error("symlink", &dst);
7453 goto exit;
7454 }
7455#endif
7456
7457 return_value = Py_None;
7458 Py_INCREF(Py_None);
7459 goto exit; /* silence "unused label" warning */
7460exit:
7461 path_cleanup(&src);
7462 path_cleanup(&dst);
7463 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007464}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007465
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007466#endif /* HAVE_SYMLINK */
7467
Larry Hastings9cf065c2012-06-22 16:30:09 -07007468
Brian Curtind40e6f72010-07-08 21:39:08 +00007469#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7470
Brian Curtind40e6f72010-07-08 21:39:08 +00007471static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007472win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007473{
7474 wchar_t *path;
7475 DWORD n_bytes_returned;
7476 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007477 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007478 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007479 HANDLE reparse_point_handle;
7480
7481 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7482 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7483 wchar_t *print_name;
7484
Larry Hastings9cf065c2012-06-22 16:30:09 -07007485 static char *keywords[] = {"path", "dir_fd", NULL};
7486
7487 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7488 &po,
7489 dir_fd_unavailable, &dir_fd
7490 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007491 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007492
Victor Stinnereb5657a2011-09-30 01:44:27 +02007493 path = PyUnicode_AsUnicode(po);
7494 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007495 return NULL;
7496
7497 /* First get a handle to the reparse point */
7498 Py_BEGIN_ALLOW_THREADS
7499 reparse_point_handle = CreateFileW(
7500 path,
7501 0,
7502 0,
7503 0,
7504 OPEN_EXISTING,
7505 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7506 0);
7507 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007508
Brian Curtind40e6f72010-07-08 21:39:08 +00007509 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007510 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007511
Brian Curtind40e6f72010-07-08 21:39:08 +00007512 Py_BEGIN_ALLOW_THREADS
7513 /* New call DeviceIoControl to read the reparse point */
7514 io_result = DeviceIoControl(
7515 reparse_point_handle,
7516 FSCTL_GET_REPARSE_POINT,
7517 0, 0, /* in buffer */
7518 target_buffer, sizeof(target_buffer),
7519 &n_bytes_returned,
7520 0 /* we're not using OVERLAPPED_IO */
7521 );
7522 CloseHandle(reparse_point_handle);
7523 Py_END_ALLOW_THREADS
7524
7525 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007526 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007527
7528 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7529 {
7530 PyErr_SetString(PyExc_ValueError,
7531 "not a symbolic link");
7532 return NULL;
7533 }
Brian Curtin74e45612010-07-09 15:58:59 +00007534 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7535 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7536
7537 result = PyUnicode_FromWideChar(print_name,
7538 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007539 return result;
7540}
7541
7542#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7543
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007544
Larry Hastings605a62d2012-06-24 04:33:36 -07007545static PyStructSequence_Field times_result_fields[] = {
7546 {"user", "user time"},
7547 {"system", "system time"},
7548 {"children_user", "user time of children"},
7549 {"children_system", "system time of children"},
7550 {"elapsed", "elapsed time since an arbitrary point in the past"},
7551 {NULL}
7552};
7553
7554PyDoc_STRVAR(times_result__doc__,
7555"times_result: Result from os.times().\n\n\
7556This object may be accessed either as a tuple of\n\
7557 (user, system, children_user, children_system, elapsed),\n\
7558or via the attributes user, system, children_user, children_system,\n\
7559and elapsed.\n\
7560\n\
7561See os.times for more information.");
7562
7563static PyStructSequence_Desc times_result_desc = {
7564 "times_result", /* name */
7565 times_result__doc__, /* doc */
7566 times_result_fields,
7567 5
7568};
7569
7570static PyTypeObject TimesResultType;
7571
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007572#ifdef MS_WINDOWS
7573#define HAVE_TIMES /* mandatory, for the method table */
7574#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007575
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007576#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007577
7578static PyObject *
7579build_times_result(double user, double system,
7580 double children_user, double children_system,
7581 double elapsed)
7582{
7583 PyObject *value = PyStructSequence_New(&TimesResultType);
7584 if (value == NULL)
7585 return NULL;
7586
7587#define SET(i, field) \
7588 { \
7589 PyObject *o = PyFloat_FromDouble(field); \
7590 if (!o) { \
7591 Py_DECREF(value); \
7592 return NULL; \
7593 } \
7594 PyStructSequence_SET_ITEM(value, i, o); \
7595 } \
7596
7597 SET(0, user);
7598 SET(1, system);
7599 SET(2, children_user);
7600 SET(3, children_system);
7601 SET(4, elapsed);
7602
7603#undef SET
7604
7605 return value;
7606}
7607
7608PyDoc_STRVAR(posix_times__doc__,
7609"times() -> times_result\n\n\
7610Return an object containing floating point numbers indicating process\n\
7611times. The object behaves like a named tuple with these fields:\n\
7612 (utime, stime, cutime, cstime, elapsed_time)");
7613
Guido van Rossumd48f2521997-12-05 22:19:34 +00007614#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7615static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007616system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007617{
7618 ULONG value = 0;
7619
7620 Py_BEGIN_ALLOW_THREADS
7621 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7622 Py_END_ALLOW_THREADS
7623
7624 return value;
7625}
7626
7627static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007628posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007629{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007630 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007631 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 (double)0 /* t.tms_utime / HZ */,
7633 (double)0 /* t.tms_stime / HZ */,
7634 (double)0 /* t.tms_cutime / HZ */,
7635 (double)0 /* t.tms_cstime / HZ */,
7636 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007637}
Larry Hastings605a62d2012-06-24 04:33:36 -07007638#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007639static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007640posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007641{
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 FILETIME create, exit, kernel, user;
7643 HANDLE hProc;
7644 hProc = GetCurrentProcess();
7645 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7646 /* The fields of a FILETIME structure are the hi and lo part
7647 of a 64-bit value expressed in 100 nanosecond units.
7648 1e7 is one second in such units; 1e-7 the inverse.
7649 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7650 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007651 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007652 (double)(user.dwHighDateTime*429.4967296 +
7653 user.dwLowDateTime*1e-7),
7654 (double)(kernel.dwHighDateTime*429.4967296 +
7655 kernel.dwLowDateTime*1e-7),
7656 (double)0,
7657 (double)0,
7658 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007659}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007660#else /* Neither Windows nor OS/2 */
7661#define NEED_TICKS_PER_SECOND
7662static long ticks_per_second = -1;
7663static PyObject *
7664posix_times(PyObject *self, PyObject *noargs)
7665{
7666 struct tms t;
7667 clock_t c;
7668 errno = 0;
7669 c = times(&t);
7670 if (c == (clock_t) -1)
7671 return posix_error();
7672 return build_times_result(
7673 (double)t.tms_utime / ticks_per_second,
7674 (double)t.tms_stime / ticks_per_second,
7675 (double)t.tms_cutime / ticks_per_second,
7676 (double)t.tms_cstime / ticks_per_second,
7677 (double)c / ticks_per_second);
7678}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007679#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007680
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007681#endif /* HAVE_TIMES */
7682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007683
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007684#ifdef HAVE_GETSID
7685PyDoc_STRVAR(posix_getsid__doc__,
7686"getsid(pid) -> sid\n\n\
7687Call the system call getsid().");
7688
7689static PyObject *
7690posix_getsid(PyObject *self, PyObject *args)
7691{
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 pid_t pid;
7693 int sid;
7694 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7695 return NULL;
7696 sid = getsid(pid);
7697 if (sid < 0)
7698 return posix_error();
7699 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007700}
7701#endif /* HAVE_GETSID */
7702
7703
Guido van Rossumb6775db1994-08-01 11:34:53 +00007704#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007705PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007706"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007707Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007708
Barry Warsaw53699e91996-12-10 23:23:01 +00007709static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007710posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007711{
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 if (setsid() < 0)
7713 return posix_error();
7714 Py_INCREF(Py_None);
7715 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007716}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007717#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007718
Guido van Rossumb6775db1994-08-01 11:34:53 +00007719#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007720PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007721"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007722Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007723
Barry Warsaw53699e91996-12-10 23:23:01 +00007724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007725posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007726{
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 pid_t pid;
7728 int pgrp;
7729 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7730 return NULL;
7731 if (setpgid(pid, pgrp) < 0)
7732 return posix_error();
7733 Py_INCREF(Py_None);
7734 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007735}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007736#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007737
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007738
Guido van Rossumb6775db1994-08-01 11:34:53 +00007739#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007740PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007741"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007742Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007743
Barry Warsaw53699e91996-12-10 23:23:01 +00007744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007745posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007746{
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 int fd;
7748 pid_t pgid;
7749 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7750 return NULL;
7751 pgid = tcgetpgrp(fd);
7752 if (pgid < 0)
7753 return posix_error();
7754 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007755}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007756#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007757
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007758
Guido van Rossumb6775db1994-08-01 11:34:53 +00007759#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007760PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007761"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007762Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007763
Barry Warsaw53699e91996-12-10 23:23:01 +00007764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007765posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007766{
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 int fd;
7768 pid_t pgid;
7769 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7770 return NULL;
7771 if (tcsetpgrp(fd, pgid) < 0)
7772 return posix_error();
7773 Py_INCREF(Py_None);
7774 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007775}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007776#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007777
Guido van Rossum687dd131993-05-17 08:34:16 +00007778/* Functions acting on file descriptors */
7779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007780PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007781"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7782Open a file for low level IO. Returns a file handle (integer).\n\
7783\n\
7784If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7785 and path should be relative; path will then be relative to that directory.\n\
7786dir_fd may not be implemented on your platform.\n\
7787 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007788
Barry Warsaw53699e91996-12-10 23:23:01 +00007789static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007790posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007791{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007792 path_t path;
7793 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007795 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007797 PyObject *return_value = NULL;
7798 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007799
Larry Hastings9cf065c2012-06-22 16:30:09 -07007800 memset(&path, 0, sizeof(path));
7801 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7802 path_converter, &path,
7803 &flags, &mode,
7804#ifdef HAVE_OPENAT
7805 dir_fd_converter, &dir_fd
7806#else
7807 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007808#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007809 ))
7810 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007811
Victor Stinner8c62be82010-05-06 00:08:46 +00007812 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007813#ifdef MS_WINDOWS
7814 if (path.wide)
7815 fd = _wopen(path.wide, flags, mode);
7816 else
7817#endif
7818#ifdef HAVE_OPENAT
7819 if (dir_fd != DEFAULT_DIR_FD)
7820 fd = openat(dir_fd, path.narrow, flags, mode);
7821 else
7822#endif
7823 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007825
Larry Hastings9cf065c2012-06-22 16:30:09 -07007826 if (fd == -1) {
7827#ifdef MS_WINDOWS
7828 /* force use of posix_error here for exact backwards compatibility */
7829 if (path.wide)
7830 return_value = posix_error();
7831 else
7832#endif
7833 return_value = path_error("open", &path);
7834 goto exit;
7835 }
7836
7837 return_value = PyLong_FromLong((long)fd);
7838
7839exit:
7840 path_cleanup(&path);
7841 return return_value;
7842}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007844PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007845"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007846Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007847
Barry Warsaw53699e91996-12-10 23:23:01 +00007848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007849posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007850{
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 int fd, res;
7852 if (!PyArg_ParseTuple(args, "i:close", &fd))
7853 return NULL;
7854 if (!_PyVerify_fd(fd))
7855 return posix_error();
7856 Py_BEGIN_ALLOW_THREADS
7857 res = close(fd);
7858 Py_END_ALLOW_THREADS
7859 if (res < 0)
7860 return posix_error();
7861 Py_INCREF(Py_None);
7862 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007863}
7864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007865
Victor Stinner8c62be82010-05-06 00:08:46 +00007866PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007867"closerange(fd_low, fd_high)\n\n\
7868Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7869
7870static PyObject *
7871posix_closerange(PyObject *self, PyObject *args)
7872{
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 int fd_from, fd_to, i;
7874 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7875 return NULL;
7876 Py_BEGIN_ALLOW_THREADS
7877 for (i = fd_from; i < fd_to; i++)
7878 if (_PyVerify_fd(i))
7879 close(i);
7880 Py_END_ALLOW_THREADS
7881 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007882}
7883
7884
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007885PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007886"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007887Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007888
Barry Warsaw53699e91996-12-10 23:23:01 +00007889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007890posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007891{
Victor Stinner8c62be82010-05-06 00:08:46 +00007892 int fd;
7893 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7894 return NULL;
7895 if (!_PyVerify_fd(fd))
7896 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007898 if (fd < 0)
7899 return posix_error();
7900 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007901}
7902
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007903
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007904PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007905"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007906Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007907
Barry Warsaw53699e91996-12-10 23:23:01 +00007908static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007909posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007910{
Victor Stinner8c62be82010-05-06 00:08:46 +00007911 int fd, fd2, res;
7912 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7913 return NULL;
7914 if (!_PyVerify_fd_dup2(fd, fd2))
7915 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007916 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007917 if (res < 0)
7918 return posix_error();
7919 Py_INCREF(Py_None);
7920 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007921}
7922
Ross Lagerwall7807c352011-03-17 20:20:30 +02007923#ifdef HAVE_LOCKF
7924PyDoc_STRVAR(posix_lockf__doc__,
7925"lockf(fd, cmd, len)\n\n\
7926Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7927fd is an open file descriptor.\n\
7928cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7929F_TEST.\n\
7930len specifies the section of the file to lock.");
7931
7932static PyObject *
7933posix_lockf(PyObject *self, PyObject *args)
7934{
7935 int fd, cmd, res;
7936 off_t len;
7937 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7938 &fd, &cmd, _parse_off_t, &len))
7939 return NULL;
7940
7941 Py_BEGIN_ALLOW_THREADS
7942 res = lockf(fd, cmd, len);
7943 Py_END_ALLOW_THREADS
7944
7945 if (res < 0)
7946 return posix_error();
7947
7948 Py_RETURN_NONE;
7949}
7950#endif
7951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007952
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007953PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007954"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007955Set the current position of a file descriptor.\n\
7956Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007957
Barry Warsaw53699e91996-12-10 23:23:01 +00007958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007959posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007960{
Victor Stinner8c62be82010-05-06 00:08:46 +00007961 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007962#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007964#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007965 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007966#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007967 PyObject *posobj;
7968 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007970#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7972 switch (how) {
7973 case 0: how = SEEK_SET; break;
7974 case 1: how = SEEK_CUR; break;
7975 case 2: how = SEEK_END; break;
7976 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007977#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007978
Ross Lagerwall8e749672011-03-17 21:54:07 +02007979#if !defined(HAVE_LARGEFILE_SUPPORT)
7980 pos = PyLong_AsLong(posobj);
7981#else
7982 pos = PyLong_AsLongLong(posobj);
7983#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 if (PyErr_Occurred())
7985 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007986
Victor Stinner8c62be82010-05-06 00:08:46 +00007987 if (!_PyVerify_fd(fd))
7988 return posix_error();
7989 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007990#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007992#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007994#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 Py_END_ALLOW_THREADS
7996 if (res < 0)
7997 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007998
7999#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008001#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008003#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008004}
8005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008007PyDoc_STRVAR(posix_read__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008008"read(fd, buffersize) -> bytes\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008009Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008010
Barry Warsaw53699e91996-12-10 23:23:01 +00008011static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008012posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008013{
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 int fd, size;
8015 Py_ssize_t n;
8016 PyObject *buffer;
8017 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
8018 return NULL;
8019 if (size < 0) {
8020 errno = EINVAL;
8021 return posix_error();
8022 }
8023 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8024 if (buffer == NULL)
8025 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00008026 if (!_PyVerify_fd(fd)) {
8027 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00008029 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 Py_BEGIN_ALLOW_THREADS
8031 n = read(fd, PyBytes_AS_STRING(buffer), size);
8032 Py_END_ALLOW_THREADS
8033 if (n < 0) {
8034 Py_DECREF(buffer);
8035 return posix_error();
8036 }
8037 if (n != size)
8038 _PyBytes_Resize(&buffer, n);
8039 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008040}
8041
Ross Lagerwall7807c352011-03-17 20:20:30 +02008042#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8043 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008044static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008045iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8046{
8047 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008048 Py_ssize_t blen, total = 0;
8049
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008050 *iov = PyMem_New(struct iovec, cnt);
8051 if (*iov == NULL) {
8052 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008053 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008054 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008055
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008056 *buf = PyMem_New(Py_buffer, cnt);
8057 if (*buf == NULL) {
8058 PyMem_Del(*iov);
8059 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008060 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 }
8062
8063 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008064 PyObject *item = PySequence_GetItem(seq, i);
8065 if (item == NULL)
8066 goto fail;
8067 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8068 Py_DECREF(item);
8069 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008071 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008072 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008073 blen = (*buf)[i].len;
8074 (*iov)[i].iov_len = blen;
8075 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008076 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008077 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008078
8079fail:
8080 PyMem_Del(*iov);
8081 for (j = 0; j < i; j++) {
8082 PyBuffer_Release(&(*buf)[j]);
8083 }
8084 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008085 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008086}
8087
8088static void
8089iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8090{
8091 int i;
8092 PyMem_Del(iov);
8093 for (i = 0; i < cnt; i++) {
8094 PyBuffer_Release(&buf[i]);
8095 }
8096 PyMem_Del(buf);
8097}
8098#endif
8099
Ross Lagerwall7807c352011-03-17 20:20:30 +02008100#ifdef HAVE_READV
8101PyDoc_STRVAR(posix_readv__doc__,
8102"readv(fd, buffers) -> bytesread\n\n\
8103Read from a file descriptor into a number of writable buffers. buffers\n\
8104is an arbitrary sequence of writable buffers.\n\
8105Returns the total number of bytes read.");
8106
8107static PyObject *
8108posix_readv(PyObject *self, PyObject *args)
8109{
8110 int fd, cnt;
8111 Py_ssize_t n;
8112 PyObject *seq;
8113 struct iovec *iov;
8114 Py_buffer *buf;
8115
8116 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
8117 return NULL;
8118 if (!PySequence_Check(seq)) {
8119 PyErr_SetString(PyExc_TypeError,
8120 "readv() arg 2 must be a sequence");
8121 return NULL;
8122 }
8123 cnt = PySequence_Size(seq);
8124
Victor Stinner57ddf782014-01-08 15:21:28 +01008125 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008126 return NULL;
8127
8128 Py_BEGIN_ALLOW_THREADS
8129 n = readv(fd, iov, cnt);
8130 Py_END_ALLOW_THREADS
8131
8132 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008133 if (n < 0)
8134 return posix_error();
8135
Ross Lagerwall7807c352011-03-17 20:20:30 +02008136 return PyLong_FromSsize_t(n);
8137}
8138#endif
8139
8140#ifdef HAVE_PREAD
8141PyDoc_STRVAR(posix_pread__doc__,
8142"pread(fd, buffersize, offset) -> string\n\n\
8143Read from a file descriptor, fd, at a position of offset. It will read up\n\
8144to buffersize number of bytes. The file offset remains unchanged.");
8145
8146static PyObject *
8147posix_pread(PyObject *self, PyObject *args)
8148{
8149 int fd, size;
8150 off_t offset;
8151 Py_ssize_t n;
8152 PyObject *buffer;
8153 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
8154 return NULL;
8155
8156 if (size < 0) {
8157 errno = EINVAL;
8158 return posix_error();
8159 }
8160 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
8161 if (buffer == NULL)
8162 return NULL;
8163 if (!_PyVerify_fd(fd)) {
8164 Py_DECREF(buffer);
8165 return posix_error();
8166 }
8167 Py_BEGIN_ALLOW_THREADS
8168 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
8169 Py_END_ALLOW_THREADS
8170 if (n < 0) {
8171 Py_DECREF(buffer);
8172 return posix_error();
8173 }
8174 if (n != size)
8175 _PyBytes_Resize(&buffer, n);
8176 return buffer;
8177}
8178#endif
8179
8180PyDoc_STRVAR(posix_write__doc__,
Benjamin Peterson3b08a292013-05-24 14:35:57 -07008181"write(fd, data) -> byteswritten\n\n\
8182Write bytes to a file descriptor.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008183
8184static PyObject *
8185posix_write(PyObject *self, PyObject *args)
8186{
8187 Py_buffer pbuf;
8188 int fd;
8189 Py_ssize_t size, len;
8190
8191 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8192 return NULL;
8193 if (!_PyVerify_fd(fd)) {
8194 PyBuffer_Release(&pbuf);
8195 return posix_error();
8196 }
8197 len = pbuf.len;
8198 Py_BEGIN_ALLOW_THREADS
8199#if defined(MS_WIN64) || defined(MS_WINDOWS)
8200 if (len > INT_MAX)
8201 len = INT_MAX;
8202 size = write(fd, pbuf.buf, (int)len);
8203#else
8204 size = write(fd, pbuf.buf, len);
8205#endif
8206 Py_END_ALLOW_THREADS
8207 PyBuffer_Release(&pbuf);
8208 if (size < 0)
8209 return posix_error();
8210 return PyLong_FromSsize_t(size);
8211}
8212
8213#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008214PyDoc_STRVAR(posix_sendfile__doc__,
8215"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8216sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8217 -> byteswritten\n\
8218Copy nbytes bytes from file descriptor in to file descriptor out.");
8219
8220static PyObject *
8221posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8222{
8223 int in, out;
8224 Py_ssize_t ret;
8225 off_t offset;
8226
8227#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8228#ifndef __APPLE__
8229 Py_ssize_t len;
8230#endif
8231 PyObject *headers = NULL, *trailers = NULL;
8232 Py_buffer *hbuf, *tbuf;
8233 off_t sbytes;
8234 struct sf_hdtr sf;
8235 int flags = 0;
8236 sf.headers = NULL;
8237 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008238 static char *keywords[] = {"out", "in",
8239 "offset", "count",
8240 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008241
8242#ifdef __APPLE__
8243 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008244 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008245#else
8246 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008247 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008248#endif
8249 &headers, &trailers, &flags))
8250 return NULL;
8251 if (headers != NULL) {
8252 if (!PySequence_Check(headers)) {
8253 PyErr_SetString(PyExc_TypeError,
8254 "sendfile() headers must be a sequence or None");
8255 return NULL;
8256 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008257 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008258 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008259 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008260 (i = iov_setup(&(sf.headers), &hbuf,
8261 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008262 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008263#ifdef __APPLE__
8264 sbytes += i;
8265#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008266 }
8267 }
8268 if (trailers != NULL) {
8269 if (!PySequence_Check(trailers)) {
8270 PyErr_SetString(PyExc_TypeError,
8271 "sendfile() trailers must be a sequence or None");
8272 return NULL;
8273 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008274 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008275 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008276 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008277 (i = iov_setup(&(sf.trailers), &tbuf,
8278 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008279 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008280#ifdef __APPLE__
8281 sbytes += i;
8282#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008283 }
8284 }
8285
8286 Py_BEGIN_ALLOW_THREADS
8287#ifdef __APPLE__
8288 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8289#else
8290 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8291#endif
8292 Py_END_ALLOW_THREADS
8293
8294 if (sf.headers != NULL)
8295 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8296 if (sf.trailers != NULL)
8297 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8298
8299 if (ret < 0) {
8300 if ((errno == EAGAIN) || (errno == EBUSY)) {
8301 if (sbytes != 0) {
8302 // some data has been sent
8303 goto done;
8304 }
8305 else {
8306 // no data has been sent; upper application is supposed
8307 // to retry on EAGAIN or EBUSY
8308 return posix_error();
8309 }
8310 }
8311 return posix_error();
8312 }
8313 goto done;
8314
8315done:
8316 #if !defined(HAVE_LARGEFILE_SUPPORT)
8317 return Py_BuildValue("l", sbytes);
8318 #else
8319 return Py_BuildValue("L", sbytes);
8320 #endif
8321
8322#else
8323 Py_ssize_t count;
8324 PyObject *offobj;
8325 static char *keywords[] = {"out", "in",
8326 "offset", "count", NULL};
8327 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8328 keywords, &out, &in, &offobj, &count))
8329 return NULL;
8330#ifdef linux
8331 if (offobj == Py_None) {
8332 Py_BEGIN_ALLOW_THREADS
8333 ret = sendfile(out, in, NULL, count);
8334 Py_END_ALLOW_THREADS
8335 if (ret < 0)
8336 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008337 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008338 }
8339#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008340 if (!_parse_off_t(offobj, &offset))
8341 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008342 Py_BEGIN_ALLOW_THREADS
8343 ret = sendfile(out, in, &offset, count);
8344 Py_END_ALLOW_THREADS
8345 if (ret < 0)
8346 return posix_error();
8347 return Py_BuildValue("n", ret);
8348#endif
8349}
8350#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008351
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008352PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008353"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008354Like stat(), but for an open file descriptor.\n\
8355Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008356
Barry Warsaw53699e91996-12-10 23:23:01 +00008357static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008358posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008359{
Victor Stinner8c62be82010-05-06 00:08:46 +00008360 int fd;
8361 STRUCT_STAT st;
8362 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008363 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008364 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008365#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 /* on OpenVMS we must ensure that all bytes are written to the file */
8367 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008368#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008369 Py_BEGIN_ALLOW_THREADS
8370 res = FSTAT(fd, &st);
8371 Py_END_ALLOW_THREADS
8372 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008373#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008375#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008377#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 }
Tim Peters5aa91602002-01-30 05:46:57 +00008379
Victor Stinner4195b5c2012-02-08 23:03:19 +01008380 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008381}
8382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008383PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008384"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008385Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008386connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008387
8388static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008389posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008390{
Victor Stinner8c62be82010-05-06 00:08:46 +00008391 int fd;
8392 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8393 return NULL;
8394 if (!_PyVerify_fd(fd))
8395 return PyBool_FromLong(0);
8396 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008397}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008398
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008399#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008400PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008401"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008402Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008403
Barry Warsaw53699e91996-12-10 23:23:01 +00008404static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008405posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008406{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008407#if defined(PYOS_OS2)
8408 HFILE read, write;
8409 APIRET rc;
8410
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008411 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008412 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008413 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008414
8415 return Py_BuildValue("(ii)", read, write);
8416#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008417#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 int fds[2];
8419 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 if (res != 0)
8422 return posix_error();
8423 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008424#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 HANDLE read, write;
8426 int read_fd, write_fd;
8427 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008429 if (!ok)
8430 return win32_error("CreatePipe", NULL);
8431 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8432 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8433 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008434#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008435#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008436}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008437#endif /* HAVE_PIPE */
8438
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008439#ifdef HAVE_PIPE2
8440PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008441"pipe2(flags) -> (read_end, write_end)\n\n\
8442Create a pipe with flags set atomically.\n\
8443flags can be constructed by ORing together one or more of these values:\n\
8444O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008445");
8446
8447static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008448posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008449{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008450 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008451 int fds[2];
8452 int res;
8453
Serhiy Storchaka9101e232013-01-19 12:41:45 +02008454 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008455 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008456 return NULL;
8457
8458 res = pipe2(fds, flags);
8459 if (res != 0)
8460 return posix_error();
8461 return Py_BuildValue("(ii)", fds[0], fds[1]);
8462}
8463#endif /* HAVE_PIPE2 */
8464
Ross Lagerwall7807c352011-03-17 20:20:30 +02008465#ifdef HAVE_WRITEV
8466PyDoc_STRVAR(posix_writev__doc__,
8467"writev(fd, buffers) -> byteswritten\n\n\
8468Write the contents of buffers to a file descriptor, where buffers is an\n\
8469arbitrary sequence of buffers.\n\
8470Returns the total bytes written.");
8471
8472static PyObject *
8473posix_writev(PyObject *self, PyObject *args)
8474{
8475 int fd, cnt;
8476 Py_ssize_t res;
8477 PyObject *seq;
8478 struct iovec *iov;
8479 Py_buffer *buf;
8480 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8481 return NULL;
8482 if (!PySequence_Check(seq)) {
8483 PyErr_SetString(PyExc_TypeError,
8484 "writev() arg 2 must be a sequence");
8485 return NULL;
8486 }
8487 cnt = PySequence_Size(seq);
8488
Victor Stinner57ddf782014-01-08 15:21:28 +01008489 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008490 return NULL;
8491 }
8492
8493 Py_BEGIN_ALLOW_THREADS
8494 res = writev(fd, iov, cnt);
8495 Py_END_ALLOW_THREADS
8496
8497 iov_cleanup(iov, buf, cnt);
Victor Stinner57ddf782014-01-08 15:21:28 +01008498 if (res < 0)
8499 return posix_error();
8500
Ross Lagerwall7807c352011-03-17 20:20:30 +02008501 return PyLong_FromSsize_t(res);
8502}
8503#endif
8504
8505#ifdef HAVE_PWRITE
8506PyDoc_STRVAR(posix_pwrite__doc__,
8507"pwrite(fd, string, offset) -> byteswritten\n\n\
8508Write string to a file descriptor, fd, from offset, leaving the file\n\
8509offset unchanged.");
8510
8511static PyObject *
8512posix_pwrite(PyObject *self, PyObject *args)
8513{
8514 Py_buffer pbuf;
8515 int fd;
8516 off_t offset;
8517 Py_ssize_t size;
8518
8519 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8520 return NULL;
8521
8522 if (!_PyVerify_fd(fd)) {
8523 PyBuffer_Release(&pbuf);
8524 return posix_error();
8525 }
8526 Py_BEGIN_ALLOW_THREADS
8527 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8528 Py_END_ALLOW_THREADS
8529 PyBuffer_Release(&pbuf);
8530 if (size < 0)
8531 return posix_error();
8532 return PyLong_FromSsize_t(size);
8533}
8534#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008535
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008536#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008537PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008538"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8539Create a FIFO (a POSIX named pipe).\n\
8540\n\
8541If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8542 and path should be relative; path will then be relative to that directory.\n\
8543dir_fd may not be implemented on your platform.\n\
8544 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008545
Barry Warsaw53699e91996-12-10 23:23:01 +00008546static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008547posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008548{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008549 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008550 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008551 int dir_fd = DEFAULT_DIR_FD;
8552 int result;
8553 PyObject *return_value = NULL;
8554 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8555
8556 memset(&path, 0, sizeof(path));
8557 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8558 path_converter, &path,
8559 &mode,
8560#ifdef HAVE_MKFIFOAT
8561 dir_fd_converter, &dir_fd
8562#else
8563 dir_fd_unavailable, &dir_fd
8564#endif
8565 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008566 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008567
Victor Stinner8c62be82010-05-06 00:08:46 +00008568 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008569#ifdef HAVE_MKFIFOAT
8570 if (dir_fd != DEFAULT_DIR_FD)
8571 result = mkfifoat(dir_fd, path.narrow, mode);
8572 else
8573#endif
8574 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008576
8577 if (result < 0) {
8578 return_value = posix_error();
8579 goto exit;
8580 }
8581
8582 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008584
8585exit:
8586 path_cleanup(&path);
8587 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008588}
8589#endif
8590
Neal Norwitz11690112002-07-30 01:08:28 +00008591#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008592PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008593"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008594Create a filesystem node (file, device special file or named pipe)\n\
8595named filename. mode specifies both the permissions to use and the\n\
8596type of node to be created, being combined (bitwise OR) with one of\n\
8597S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008598device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008599os.makedev()), otherwise it is ignored.\n\
8600\n\
8601If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8602 and path should be relative; path will then be relative to that directory.\n\
8603dir_fd may not be implemented on your platform.\n\
8604 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008605
8606
8607static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008608posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008609{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008610 path_t path;
8611 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008612 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008613 int dir_fd = DEFAULT_DIR_FD;
8614 int result;
8615 PyObject *return_value = NULL;
8616 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8617
8618 memset(&path, 0, sizeof(path));
8619 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8620 path_converter, &path,
8621 &mode, &device,
8622#ifdef HAVE_MKNODAT
8623 dir_fd_converter, &dir_fd
8624#else
8625 dir_fd_unavailable, &dir_fd
8626#endif
8627 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008628 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008629
Victor Stinner8c62be82010-05-06 00:08:46 +00008630 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008631#ifdef HAVE_MKNODAT
8632 if (dir_fd != DEFAULT_DIR_FD)
8633 result = mknodat(dir_fd, path.narrow, mode, device);
8634 else
8635#endif
8636 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008637 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008638
8639 if (result < 0) {
8640 return_value = posix_error();
8641 goto exit;
8642 }
8643
8644 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008645 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008646
Larry Hastings9cf065c2012-06-22 16:30:09 -07008647exit:
8648 path_cleanup(&path);
8649 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008650}
8651#endif
8652
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008653#ifdef HAVE_DEVICE_MACROS
8654PyDoc_STRVAR(posix_major__doc__,
8655"major(device) -> major number\n\
8656Extracts a device major number from a raw device number.");
8657
8658static PyObject *
8659posix_major(PyObject *self, PyObject *args)
8660{
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 int device;
8662 if (!PyArg_ParseTuple(args, "i:major", &device))
8663 return NULL;
8664 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008665}
8666
8667PyDoc_STRVAR(posix_minor__doc__,
8668"minor(device) -> minor number\n\
8669Extracts a device minor number from a raw device number.");
8670
8671static PyObject *
8672posix_minor(PyObject *self, PyObject *args)
8673{
Victor Stinner8c62be82010-05-06 00:08:46 +00008674 int device;
8675 if (!PyArg_ParseTuple(args, "i:minor", &device))
8676 return NULL;
8677 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008678}
8679
8680PyDoc_STRVAR(posix_makedev__doc__,
8681"makedev(major, minor) -> device number\n\
8682Composes a raw device number from the major and minor device numbers.");
8683
8684static PyObject *
8685posix_makedev(PyObject *self, PyObject *args)
8686{
Victor Stinner8c62be82010-05-06 00:08:46 +00008687 int major, minor;
8688 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8689 return NULL;
8690 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008691}
8692#endif /* device macros */
8693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008694
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008695#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008696PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008697"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008698Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008699
Barry Warsaw53699e91996-12-10 23:23:01 +00008700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008701posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008702{
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 int fd;
8704 off_t length;
8705 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008706
Ross Lagerwall7807c352011-03-17 20:20:30 +02008707 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008709
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 Py_BEGIN_ALLOW_THREADS
8711 res = ftruncate(fd, length);
8712 Py_END_ALLOW_THREADS
8713 if (res < 0)
8714 return posix_error();
8715 Py_INCREF(Py_None);
8716 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008717}
8718#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008719
Ross Lagerwall7807c352011-03-17 20:20:30 +02008720#ifdef HAVE_TRUNCATE
8721PyDoc_STRVAR(posix_truncate__doc__,
8722"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008723Truncate the file given by path to length bytes.\n\
8724On some platforms, path may also be specified as an open file descriptor.\n\
8725 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008726
8727static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008728posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008729{
Georg Brandl306336b2012-06-24 12:55:33 +02008730 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008731 off_t length;
8732 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008733 PyObject *result = NULL;
8734 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008735
Georg Brandl306336b2012-06-24 12:55:33 +02008736 memset(&path, 0, sizeof(path));
8737#ifdef HAVE_FTRUNCATE
8738 path.allow_fd = 1;
8739#endif
8740 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8741 path_converter, &path,
8742 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008743 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008744
8745 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008746#ifdef HAVE_FTRUNCATE
8747 if (path.fd != -1)
8748 res = ftruncate(path.fd, length);
8749 else
8750#endif
8751 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008752 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008753 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008754 result = path_posix_error("truncate", &path);
8755 else {
8756 Py_INCREF(Py_None);
8757 result = Py_None;
8758 }
8759 path_cleanup(&path);
8760 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008761}
8762#endif
8763
8764#ifdef HAVE_POSIX_FALLOCATE
8765PyDoc_STRVAR(posix_posix_fallocate__doc__,
8766"posix_fallocate(fd, offset, len)\n\n\
8767Ensures that enough disk space is allocated for the file specified by fd\n\
8768starting from offset and continuing for len bytes.");
8769
8770static PyObject *
8771posix_posix_fallocate(PyObject *self, PyObject *args)
8772{
8773 off_t len, offset;
8774 int res, fd;
8775
8776 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8777 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8778 return NULL;
8779
8780 Py_BEGIN_ALLOW_THREADS
8781 res = posix_fallocate(fd, offset, len);
8782 Py_END_ALLOW_THREADS
8783 if (res != 0) {
8784 errno = res;
8785 return posix_error();
8786 }
8787 Py_RETURN_NONE;
8788}
8789#endif
8790
8791#ifdef HAVE_POSIX_FADVISE
8792PyDoc_STRVAR(posix_posix_fadvise__doc__,
8793"posix_fadvise(fd, offset, len, advice)\n\n\
8794Announces an intention to access data in a specific pattern thus allowing\n\
8795the kernel to make optimizations.\n\
8796The advice applies to the region of the file specified by fd starting at\n\
8797offset and continuing for len bytes.\n\
8798advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8799POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8800POSIX_FADV_DONTNEED.");
8801
8802static PyObject *
8803posix_posix_fadvise(PyObject *self, PyObject *args)
8804{
8805 off_t len, offset;
8806 int res, fd, advice;
8807
8808 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8809 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8810 return NULL;
8811
8812 Py_BEGIN_ALLOW_THREADS
8813 res = posix_fadvise(fd, offset, len, advice);
8814 Py_END_ALLOW_THREADS
8815 if (res != 0) {
8816 errno = res;
8817 return posix_error();
8818 }
8819 Py_RETURN_NONE;
8820}
8821#endif
8822
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008823#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008824PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008825"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008826Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008827
Fred Drake762e2061999-08-26 17:23:54 +00008828/* Save putenv() parameters as values here, so we can collect them when they
8829 * get re-set with another call for the same key. */
8830static PyObject *posix_putenv_garbage;
8831
Tim Peters5aa91602002-01-30 05:46:57 +00008832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008833posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008834{
Victor Stinner84ae1182010-05-06 22:05:07 +00008835 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008836#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008837 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008838 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008839
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008841 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008842 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008843 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008844
Victor Stinner65170952011-11-22 22:16:17 +01008845 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008846 if (newstr == NULL) {
8847 PyErr_NoMemory();
8848 goto error;
8849 }
Victor Stinner65170952011-11-22 22:16:17 +01008850 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8851 PyErr_Format(PyExc_ValueError,
8852 "the environment variable is longer than %u characters",
8853 _MAX_ENV);
8854 goto error;
8855 }
8856
Victor Stinner8c62be82010-05-06 00:08:46 +00008857 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008858 if (newenv == NULL)
8859 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008861 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008862 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008863 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008864#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008865 PyObject *os1, *os2;
8866 char *s1, *s2;
8867 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008868
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008869 if (!PyArg_ParseTuple(args,
8870 "O&O&:putenv",
8871 PyUnicode_FSConverter, &os1,
8872 PyUnicode_FSConverter, &os2))
8873 return NULL;
8874 s1 = PyBytes_AsString(os1);
8875 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008876
Victor Stinner65170952011-11-22 22:16:17 +01008877 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008878 if (newstr == NULL) {
8879 PyErr_NoMemory();
8880 goto error;
8881 }
8882
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008885 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008886 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008887 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008888#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008889
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 /* Install the first arg and newstr in posix_putenv_garbage;
8891 * this will cause previous value to be collected. This has to
8892 * happen after the real putenv() call because the old value
8893 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008894 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 /* really not much we can do; just leak */
8896 PyErr_Clear();
8897 }
8898 else {
8899 Py_DECREF(newstr);
8900 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008901
Martin v. Löwis011e8422009-05-05 04:43:17 +00008902#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008903 Py_DECREF(os1);
8904 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008905#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008906 Py_RETURN_NONE;
8907
8908error:
8909#ifndef MS_WINDOWS
8910 Py_DECREF(os1);
8911 Py_DECREF(os2);
8912#endif
8913 Py_XDECREF(newstr);
8914 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008915}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008916#endif /* putenv */
8917
Guido van Rossumc524d952001-10-19 01:31:59 +00008918#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008919PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008920"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008921Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008922
8923static PyObject *
8924posix_unsetenv(PyObject *self, PyObject *args)
8925{
Victor Stinner65170952011-11-22 22:16:17 +01008926 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008927#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008928 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008929#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008930
8931 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008932
Victor Stinner65170952011-11-22 22:16:17 +01008933 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008934 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008935
Victor Stinner984890f2011-11-24 13:53:38 +01008936#ifdef HAVE_BROKEN_UNSETENV
8937 unsetenv(PyBytes_AS_STRING(name));
8938#else
Victor Stinner65170952011-11-22 22:16:17 +01008939 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008940 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008941 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008942 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008943 }
Victor Stinner984890f2011-11-24 13:53:38 +01008944#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008945
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 /* Remove the key from posix_putenv_garbage;
8947 * this will cause it to be collected. This has to
8948 * happen after the real unsetenv() call because the
8949 * old value was still accessible until then.
8950 */
Victor Stinner65170952011-11-22 22:16:17 +01008951 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008952 /* really not much we can do; just leak */
8953 PyErr_Clear();
8954 }
Victor Stinner65170952011-11-22 22:16:17 +01008955 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008956 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008957}
8958#endif /* unsetenv */
8959
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008960PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008961"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008962Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008963
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008965posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008966{
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 int code;
8968 char *message;
8969 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8970 return NULL;
8971 message = strerror(code);
8972 if (message == NULL) {
8973 PyErr_SetString(PyExc_ValueError,
8974 "strerror() argument out of range");
8975 return NULL;
8976 }
Victor Stinner1b579672011-12-17 05:47:23 +01008977 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008978}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008979
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008980
Guido van Rossumc9641791998-08-04 15:26:23 +00008981#ifdef HAVE_SYS_WAIT_H
8982
Fred Drake106c1a02002-04-23 15:58:02 +00008983#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008984PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008985"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008986Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008987
8988static PyObject *
8989posix_WCOREDUMP(PyObject *self, PyObject *args)
8990{
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 WAIT_TYPE status;
8992 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008993
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8995 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008996
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008998}
8999#endif /* WCOREDUMP */
9000
9001#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009002PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009003"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00009004Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009005job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00009006
9007static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009008posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00009009{
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 WAIT_TYPE status;
9011 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00009012
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
9014 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00009015
Victor Stinner8c62be82010-05-06 00:08:46 +00009016 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00009017}
9018#endif /* WIFCONTINUED */
9019
Guido van Rossumc9641791998-08-04 15:26:23 +00009020#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009021PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009022"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009023Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009024
9025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009026posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009027{
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 WAIT_TYPE status;
9029 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009030
Victor Stinner8c62be82010-05-06 00:08:46 +00009031 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
9032 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009033
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009035}
9036#endif /* WIFSTOPPED */
9037
9038#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009039PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009040"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009041Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009042
9043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009044posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009045{
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 WAIT_TYPE status;
9047 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009048
Victor Stinner8c62be82010-05-06 00:08:46 +00009049 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
9050 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009051
Victor Stinner8c62be82010-05-06 00:08:46 +00009052 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009053}
9054#endif /* WIFSIGNALED */
9055
9056#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009057PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009058"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009059Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009060system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009061
9062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009063posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009064{
Victor Stinner8c62be82010-05-06 00:08:46 +00009065 WAIT_TYPE status;
9066 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009067
Victor Stinner8c62be82010-05-06 00:08:46 +00009068 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
9069 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009070
Victor Stinner8c62be82010-05-06 00:08:46 +00009071 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009072}
9073#endif /* WIFEXITED */
9074
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009075#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009076PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009077"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009078Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009079
9080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009081posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009082{
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 WAIT_TYPE status;
9084 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009085
Victor Stinner8c62be82010-05-06 00:08:46 +00009086 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
9087 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009088
Victor Stinner8c62be82010-05-06 00:08:46 +00009089 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009090}
9091#endif /* WEXITSTATUS */
9092
9093#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009094PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009095"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00009096Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009097value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009098
9099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009100posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009101{
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 WAIT_TYPE status;
9103 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009104
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
9106 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009107
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009109}
9110#endif /* WTERMSIG */
9111
9112#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009113PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009114"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009115Return the signal that stopped the process that provided\n\
9116the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00009117
9118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009119posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00009120{
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 WAIT_TYPE status;
9122 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00009123
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
9125 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00009126
Victor Stinner8c62be82010-05-06 00:08:46 +00009127 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00009128}
9129#endif /* WSTOPSIG */
9130
9131#endif /* HAVE_SYS_WAIT_H */
9132
9133
Thomas Wouters477c8d52006-05-27 19:21:47 +00009134#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009135#ifdef _SCO_DS
9136/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9137 needed definitions in sys/statvfs.h */
9138#define _SVID3
9139#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009140#include <sys/statvfs.h>
9141
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009142static PyObject*
9143_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9145 if (v == NULL)
9146 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009147
9148#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009149 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9150 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9151 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9152 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9153 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9154 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9155 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9156 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9157 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9158 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009159#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009160 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9161 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9162 PyStructSequence_SET_ITEM(v, 2,
9163 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9164 PyStructSequence_SET_ITEM(v, 3,
9165 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9166 PyStructSequence_SET_ITEM(v, 4,
9167 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9168 PyStructSequence_SET_ITEM(v, 5,
9169 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9170 PyStructSequence_SET_ITEM(v, 6,
9171 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9172 PyStructSequence_SET_ITEM(v, 7,
9173 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9174 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9175 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009176#endif
9177
Victor Stinner8c62be82010-05-06 00:08:46 +00009178 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009179}
9180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009181PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009182"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009183Perform an fstatvfs system call on the given fd.\n\
9184Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009185
9186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009187posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009188{
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 int fd, res;
9190 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009191
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9193 return NULL;
9194 Py_BEGIN_ALLOW_THREADS
9195 res = fstatvfs(fd, &st);
9196 Py_END_ALLOW_THREADS
9197 if (res != 0)
9198 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009199
Victor Stinner8c62be82010-05-06 00:08:46 +00009200 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009201}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009202#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009203
9204
Thomas Wouters477c8d52006-05-27 19:21:47 +00009205#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009206#include <sys/statvfs.h>
9207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009208PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009209"statvfs(path)\n\n\
9210Perform a statvfs system call on the given path.\n\
9211\n\
9212path may always be specified as a string.\n\
9213On some platforms, path may also be specified as an open file descriptor.\n\
9214 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009215
9216static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009217posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009218{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009219 static char *keywords[] = {"path", NULL};
9220 path_t path;
9221 int result;
9222 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009223 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009224
Larry Hastings9cf065c2012-06-22 16:30:09 -07009225 memset(&path, 0, sizeof(path));
9226#ifdef HAVE_FSTATVFS
9227 path.allow_fd = 1;
9228#endif
9229 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9230 path_converter, &path
9231 ))
9232 return NULL;
9233
9234 Py_BEGIN_ALLOW_THREADS
9235#ifdef HAVE_FSTATVFS
9236 if (path.fd != -1) {
9237#ifdef __APPLE__
9238 /* handle weak-linking on Mac OS X 10.3 */
9239 if (fstatvfs == NULL) {
9240 fd_specified("statvfs", path.fd);
9241 goto exit;
9242 }
9243#endif
9244 result = fstatvfs(path.fd, &st);
9245 }
9246 else
9247#endif
9248 result = statvfs(path.narrow, &st);
9249 Py_END_ALLOW_THREADS
9250
9251 if (result) {
9252 return_value = path_posix_error("statvfs", &path);
9253 goto exit;
9254 }
9255
9256 return_value = _pystatvfs_fromstructstatvfs(st);
9257
9258exit:
9259 path_cleanup(&path);
9260 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009261}
9262#endif /* HAVE_STATVFS */
9263
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009264#ifdef MS_WINDOWS
9265PyDoc_STRVAR(win32__getdiskusage__doc__,
9266"_getdiskusage(path) -> (total, free)\n\n\
9267Return disk usage statistics about the given path as (total, free) tuple.");
9268
9269static PyObject *
9270win32__getdiskusage(PyObject *self, PyObject *args)
9271{
9272 BOOL retval;
9273 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009274 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009275
Victor Stinner6139c1b2011-11-09 22:14:14 +01009276 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009277 return NULL;
9278
9279 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009280 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009281 Py_END_ALLOW_THREADS
9282 if (retval == 0)
9283 return PyErr_SetFromWindowsErr(0);
9284
9285 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9286}
9287#endif
9288
9289
Fred Drakec9680921999-12-13 16:37:25 +00009290/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9291 * It maps strings representing configuration variable names to
9292 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009293 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009294 * rarely-used constants. There are three separate tables that use
9295 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009296 *
9297 * This code is always included, even if none of the interfaces that
9298 * need it are included. The #if hackery needed to avoid it would be
9299 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009300 */
9301struct constdef {
9302 char *name;
9303 long value;
9304};
9305
Fred Drake12c6e2d1999-12-14 21:25:03 +00009306static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009307conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009308 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009309{
Christian Heimes217cfd12007-12-02 14:31:20 +00009310 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009311 *valuep = PyLong_AS_LONG(arg);
9312 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009313 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009314 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009315 /* look up the value in the table using a binary search */
9316 size_t lo = 0;
9317 size_t mid;
9318 size_t hi = tablesize;
9319 int cmp;
9320 const char *confname;
9321 if (!PyUnicode_Check(arg)) {
9322 PyErr_SetString(PyExc_TypeError,
9323 "configuration names must be strings or integers");
9324 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009326 confname = _PyUnicode_AsString(arg);
9327 if (confname == NULL)
9328 return 0;
9329 while (lo < hi) {
9330 mid = (lo + hi) / 2;
9331 cmp = strcmp(confname, table[mid].name);
9332 if (cmp < 0)
9333 hi = mid;
9334 else if (cmp > 0)
9335 lo = mid + 1;
9336 else {
9337 *valuep = table[mid].value;
9338 return 1;
9339 }
9340 }
9341 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9342 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009344}
9345
9346
9347#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9348static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009349#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009350 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009351#endif
9352#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009353 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009354#endif
Fred Drakec9680921999-12-13 16:37:25 +00009355#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009356 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009357#endif
9358#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009360#endif
9361#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009363#endif
9364#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009365 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009366#endif
9367#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009369#endif
9370#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009371 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009372#endif
9373#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009374 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009375#endif
9376#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009378#endif
9379#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009381#endif
9382#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009384#endif
9385#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009387#endif
9388#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009389 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009390#endif
9391#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009393#endif
9394#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009396#endif
9397#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009399#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009400#ifdef _PC_ACL_ENABLED
9401 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9402#endif
9403#ifdef _PC_MIN_HOLE_SIZE
9404 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9405#endif
9406#ifdef _PC_ALLOC_SIZE_MIN
9407 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9408#endif
9409#ifdef _PC_REC_INCR_XFER_SIZE
9410 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9411#endif
9412#ifdef _PC_REC_MAX_XFER_SIZE
9413 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9414#endif
9415#ifdef _PC_REC_MIN_XFER_SIZE
9416 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9417#endif
9418#ifdef _PC_REC_XFER_ALIGN
9419 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9420#endif
9421#ifdef _PC_SYMLINK_MAX
9422 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9423#endif
9424#ifdef _PC_XATTR_ENABLED
9425 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9426#endif
9427#ifdef _PC_XATTR_EXISTS
9428 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9429#endif
9430#ifdef _PC_TIMESTAMP_RESOLUTION
9431 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9432#endif
Fred Drakec9680921999-12-13 16:37:25 +00009433};
9434
Fred Drakec9680921999-12-13 16:37:25 +00009435static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009436conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009437{
9438 return conv_confname(arg, valuep, posix_constants_pathconf,
9439 sizeof(posix_constants_pathconf)
9440 / sizeof(struct constdef));
9441}
9442#endif
9443
9444#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009445PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009446"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009447Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009448If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009449
9450static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009451posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009452{
9453 PyObject *result = NULL;
9454 int name, fd;
9455
Fred Drake12c6e2d1999-12-14 21:25:03 +00009456 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9457 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009458 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009459
Stefan Krah0e803b32010-11-26 16:16:47 +00009460 errno = 0;
9461 limit = fpathconf(fd, name);
9462 if (limit == -1 && errno != 0)
9463 posix_error();
9464 else
9465 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009466 }
9467 return result;
9468}
9469#endif
9470
9471
9472#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009473PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009474"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009475Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009476If there is no limit, return -1.\n\
9477On some platforms, path may also be specified as an open file descriptor.\n\
9478 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009479
9480static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009481posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009482{
Georg Brandl306336b2012-06-24 12:55:33 +02009483 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009484 PyObject *result = NULL;
9485 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009486 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009487
Georg Brandl306336b2012-06-24 12:55:33 +02009488 memset(&path, 0, sizeof(path));
9489#ifdef HAVE_FPATHCONF
9490 path.allow_fd = 1;
9491#endif
9492 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9493 path_converter, &path,
9494 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009496
Victor Stinner8c62be82010-05-06 00:08:46 +00009497 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009498#ifdef HAVE_FPATHCONF
9499 if (path.fd != -1)
9500 limit = fpathconf(path.fd, name);
9501 else
9502#endif
9503 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 if (limit == -1 && errno != 0) {
9505 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009506 /* could be a path or name problem */
9507 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009508 else
Georg Brandl306336b2012-06-24 12:55:33 +02009509 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 }
9511 else
9512 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009513 }
Georg Brandl306336b2012-06-24 12:55:33 +02009514 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009515 return result;
9516}
9517#endif
9518
9519#ifdef HAVE_CONFSTR
9520static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009521#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009523#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009524#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009526#endif
9527#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009529#endif
Fred Draked86ed291999-12-15 15:34:33 +00009530#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009532#endif
9533#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009535#endif
9536#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009538#endif
9539#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009541#endif
Fred Drakec9680921999-12-13 16:37:25 +00009542#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
Fred Draked86ed291999-12-15 15:34:33 +00009566#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009568#endif
Fred Drakec9680921999-12-13 16:37:25 +00009569#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
Fred Draked86ed291999-12-15 15:34:33 +00009572#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009574#endif
9575#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009577#endif
9578#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009580#endif
9581#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009583#endif
Fred Drakec9680921999-12-13 16:37:25 +00009584#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
9590#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009592#endif
9593#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
9602#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
9611#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009613#endif
9614#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
9629#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009630 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009631#endif
Fred Draked86ed291999-12-15 15:34:33 +00009632#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009633 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009634#endif
9635#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009636 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009637#endif
9638#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009639 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009640#endif
9641#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009643#endif
9644#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009646#endif
9647#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009649#endif
9650#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009652#endif
9653#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009655#endif
9656#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009658#endif
9659#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009661#endif
9662#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009664#endif
9665#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009667#endif
9668#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009670#endif
Fred Drakec9680921999-12-13 16:37:25 +00009671};
9672
9673static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009674conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009675{
9676 return conv_confname(arg, valuep, posix_constants_confstr,
9677 sizeof(posix_constants_confstr)
9678 / sizeof(struct constdef));
9679}
9680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009681PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009682"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009683Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009684
9685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009686posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009687{
9688 PyObject *result = NULL;
9689 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009690 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009691 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009692
Victor Stinnercb043522010-09-10 23:49:04 +00009693 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9694 return NULL;
9695
9696 errno = 0;
9697 len = confstr(name, buffer, sizeof(buffer));
9698 if (len == 0) {
9699 if (errno) {
9700 posix_error();
9701 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009702 }
9703 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009704 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009705 }
9706 }
Victor Stinnercb043522010-09-10 23:49:04 +00009707
9708 if ((unsigned int)len >= sizeof(buffer)) {
9709 char *buf = PyMem_Malloc(len);
9710 if (buf == NULL)
9711 return PyErr_NoMemory();
9712 confstr(name, buf, len);
9713 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9714 PyMem_Free(buf);
9715 }
9716 else
9717 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009718 return result;
9719}
9720#endif
9721
9722
9723#ifdef HAVE_SYSCONF
9724static struct constdef posix_constants_sysconf[] = {
9725#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
Fred Draked86ed291999-12-15 15:34:33 +00009755#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
9758#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
Fred Drakec9680921999-12-13 16:37:25 +00009761#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
Fred Drakec9680921999-12-13 16:37:25 +00009764#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
Fred Draked86ed291999-12-15 15:34:33 +00009779#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009781#endif
Fred Drakec9680921999-12-13 16:37:25 +00009782#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
Fred Draked86ed291999-12-15 15:34:33 +00009797#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
Fred Drakec9680921999-12-13 16:37:25 +00009800#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
9854#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009856#endif
9857#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
Fred Draked86ed291999-12-15 15:34:33 +00009869#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009871#endif
Fred Drakec9680921999-12-13 16:37:25 +00009872#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
Fred Draked86ed291999-12-15 15:34:33 +00009881#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009883#endif
Fred Drakec9680921999-12-13 16:37:25 +00009884#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
Fred Draked86ed291999-12-15 15:34:33 +00009887#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009889#endif
9890#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009892#endif
Fred Drakec9680921999-12-13 16:37:25 +00009893#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
Fred Draked86ed291999-12-15 15:34:33 +00009905#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009907#endif
Fred Drakec9680921999-12-13 16:37:25 +00009908#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
Fred Draked86ed291999-12-15 15:34:33 +00009929#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009931#endif
Fred Drakec9680921999-12-13 16:37:25 +00009932#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
Fred Draked86ed291999-12-15 15:34:33 +00009938#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009940#endif
Fred Drakec9680921999-12-13 16:37:25 +00009941#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
Fred Draked86ed291999-12-15 15:34:33 +00009968#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009970#endif
9971#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009973#endif
Fred Drakec9680921999-12-13 16:37:25 +00009974#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
Fred Draked86ed291999-12-15 15:34:33 +000010079#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010081#endif
Fred Drakec9680921999-12-13 16:37:25 +000010082#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217};
10218
10219static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010220conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010221{
10222 return conv_confname(arg, valuep, posix_constants_sysconf,
10223 sizeof(posix_constants_sysconf)
10224 / sizeof(struct constdef));
10225}
10226
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010227PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010228"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010229Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010230
10231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010232posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010233{
10234 PyObject *result = NULL;
10235 int name;
10236
10237 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10238 int value;
10239
10240 errno = 0;
10241 value = sysconf(name);
10242 if (value == -1 && errno != 0)
10243 posix_error();
10244 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010245 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010246 }
10247 return result;
10248}
10249#endif
10250
10251
Fred Drakebec628d1999-12-15 18:31:10 +000010252/* This code is used to ensure that the tables of configuration value names
10253 * are in sorted order as required by conv_confname(), and also to build the
10254 * the exported dictionaries that are used to publish information about the
10255 * names available on the host platform.
10256 *
10257 * Sorting the table at runtime ensures that the table is properly ordered
10258 * when used, even for platforms we're not able to test on. It also makes
10259 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010260 */
Fred Drakebec628d1999-12-15 18:31:10 +000010261
10262static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010263cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010264{
10265 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010267 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010269
10270 return strcmp(c1->name, c2->name);
10271}
10272
10273static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010274setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010276{
Fred Drakebec628d1999-12-15 18:31:10 +000010277 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010278 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010279
10280 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10281 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010282 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010284
Barry Warsaw3155db32000-04-13 15:20:40 +000010285 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 PyObject *o = PyLong_FromLong(table[i].value);
10287 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10288 Py_XDECREF(o);
10289 Py_DECREF(d);
10290 return -1;
10291 }
10292 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010293 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010294 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010295}
10296
Fred Drakebec628d1999-12-15 18:31:10 +000010297/* Return -1 on failure, 0 on success. */
10298static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010299setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010300{
10301#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010302 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010303 sizeof(posix_constants_pathconf)
10304 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010305 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010306 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010307#endif
10308#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010309 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010310 sizeof(posix_constants_confstr)
10311 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010312 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010313 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010314#endif
10315#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010316 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010317 sizeof(posix_constants_sysconf)
10318 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010319 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010320 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010321#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010322 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010323}
Fred Draked86ed291999-12-15 15:34:33 +000010324
10325
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010326PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010327"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010328Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010329in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010330
10331static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010332posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010333{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010334 abort();
10335 /*NOTREACHED*/
10336 Py_FatalError("abort() called from Python code didn't abort!");
10337 return NULL;
10338}
Fred Drakebec628d1999-12-15 18:31:10 +000010339
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010340#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010341PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010342"startfile(filepath [, operation]) - Start a file with its associated\n\
10343application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010344\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010345When \"operation\" is not specified or \"open\", this acts like\n\
10346double-clicking the file in Explorer, or giving the file name as an\n\
10347argument to the DOS \"start\" command: the file is opened with whatever\n\
10348application (if any) its extension is associated.\n\
10349When another \"operation\" is given, it specifies what should be done with\n\
10350the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010351\n\
10352startfile returns as soon as the associated application is launched.\n\
10353There is no option to wait for the application to close, and no way\n\
10354to retrieve the application's exit status.\n\
10355\n\
10356The filepath is relative to the current directory. If you want to use\n\
10357an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010358the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010359
10360static PyObject *
10361win32_startfile(PyObject *self, PyObject *args)
10362{
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 PyObject *ofilepath;
10364 char *filepath;
10365 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010366 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010368
Victor Stinnereb5657a2011-09-30 01:44:27 +020010369 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 if (!PyArg_ParseTuple(args, "U|s:startfile",
10371 &unipath, &operation)) {
10372 PyErr_Clear();
10373 goto normal;
10374 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010375
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010377 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010379 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 PyErr_Clear();
10381 operation = NULL;
10382 goto normal;
10383 }
10384 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010385
Victor Stinnereb5657a2011-09-30 01:44:27 +020010386 wpath = PyUnicode_AsUnicode(unipath);
10387 if (wpath == NULL)
10388 goto normal;
10389 if (uoperation) {
10390 woperation = PyUnicode_AsUnicode(uoperation);
10391 if (woperation == NULL)
10392 goto normal;
10393 }
10394 else
10395 woperation = NULL;
10396
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010398 rc = ShellExecuteW((HWND)0, woperation, wpath,
10399 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 Py_END_ALLOW_THREADS
10401
Victor Stinnereb5657a2011-09-30 01:44:27 +020010402 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010404 win32_error_object("startfile", unipath);
10405 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 }
10407 Py_INCREF(Py_None);
10408 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010409
10410normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10412 PyUnicode_FSConverter, &ofilepath,
10413 &operation))
10414 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010415 if (win32_warn_bytes_api()) {
10416 Py_DECREF(ofilepath);
10417 return NULL;
10418 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010419 filepath = PyBytes_AsString(ofilepath);
10420 Py_BEGIN_ALLOW_THREADS
10421 rc = ShellExecute((HWND)0, operation, filepath,
10422 NULL, NULL, SW_SHOWNORMAL);
10423 Py_END_ALLOW_THREADS
10424 if (rc <= (HINSTANCE)32) {
10425 PyObject *errval = win32_error("startfile", filepath);
10426 Py_DECREF(ofilepath);
10427 return errval;
10428 }
10429 Py_DECREF(ofilepath);
10430 Py_INCREF(Py_None);
10431 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010432}
10433#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010434
Martin v. Löwis438b5342002-12-27 10:16:42 +000010435#ifdef HAVE_GETLOADAVG
10436PyDoc_STRVAR(posix_getloadavg__doc__,
10437"getloadavg() -> (float, float, float)\n\n\
10438Return the number of processes in the system run queue averaged over\n\
10439the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10440was unobtainable");
10441
10442static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010443posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010444{
10445 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010446 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010447 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10448 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010449 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010450 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010451}
10452#endif
10453
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010454PyDoc_STRVAR(device_encoding__doc__,
10455"device_encoding(fd) -> str\n\n\
10456Return a string describing the encoding of the device\n\
10457if the output is a terminal; else return None.");
10458
10459static PyObject *
10460device_encoding(PyObject *self, PyObject *args)
10461{
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010463
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10465 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010466
10467 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010468}
10469
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010470#ifdef HAVE_SETRESUID
10471PyDoc_STRVAR(posix_setresuid__doc__,
10472"setresuid(ruid, euid, suid)\n\n\
10473Set the current process's real, effective, and saved user ids.");
10474
10475static PyObject*
10476posix_setresuid (PyObject *self, PyObject *args)
10477{
Victor Stinner8c62be82010-05-06 00:08:46 +000010478 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010479 uid_t ruid, euid, suid;
10480 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10481 _Py_Uid_Converter, &ruid,
10482 _Py_Uid_Converter, &euid,
10483 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 return NULL;
10485 if (setresuid(ruid, euid, suid) < 0)
10486 return posix_error();
10487 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010488}
10489#endif
10490
10491#ifdef HAVE_SETRESGID
10492PyDoc_STRVAR(posix_setresgid__doc__,
10493"setresgid(rgid, egid, sgid)\n\n\
10494Set the current process's real, effective, and saved group ids.");
10495
10496static PyObject*
10497posix_setresgid (PyObject *self, PyObject *args)
10498{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010499 gid_t rgid, egid, sgid;
10500 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10501 _Py_Gid_Converter, &rgid,
10502 _Py_Gid_Converter, &egid,
10503 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 return NULL;
10505 if (setresgid(rgid, egid, sgid) < 0)
10506 return posix_error();
10507 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010508}
10509#endif
10510
10511#ifdef HAVE_GETRESUID
10512PyDoc_STRVAR(posix_getresuid__doc__,
10513"getresuid() -> (ruid, euid, suid)\n\n\
10514Get tuple of the current process's real, effective, and saved user ids.");
10515
10516static PyObject*
10517posix_getresuid (PyObject *self, PyObject *noargs)
10518{
Victor Stinner8c62be82010-05-06 00:08:46 +000010519 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010520 if (getresuid(&ruid, &euid, &suid) < 0)
10521 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010522 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10523 _PyLong_FromUid(euid),
10524 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010525}
10526#endif
10527
10528#ifdef HAVE_GETRESGID
10529PyDoc_STRVAR(posix_getresgid__doc__,
10530"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010531Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010532
10533static PyObject*
10534posix_getresgid (PyObject *self, PyObject *noargs)
10535{
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 if (getresgid(&rgid, &egid, &sgid) < 0)
10538 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010539 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10540 _PyLong_FromGid(egid),
10541 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010542}
10543#endif
10544
Benjamin Peterson9428d532011-09-14 11:45:52 -040010545#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010546
Benjamin Peterson799bd802011-08-31 22:15:17 -040010547PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010548"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10549Return the value of extended attribute attribute on path.\n\
10550\n\
10551path may be either a string or an open file descriptor.\n\
10552If follow_symlinks is False, and the last element of the path is a symbolic\n\
10553 link, getxattr will examine the symbolic link itself instead of the file\n\
10554 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010555
10556static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010557posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010558{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010559 path_t path;
10560 path_t attribute;
10561 int follow_symlinks = 1;
10562 PyObject *buffer = NULL;
10563 int i;
10564 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010565
Larry Hastings9cf065c2012-06-22 16:30:09 -070010566 memset(&path, 0, sizeof(path));
10567 memset(&attribute, 0, sizeof(attribute));
10568 path.allow_fd = 1;
10569 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10570 path_converter, &path,
10571 path_converter, &attribute,
10572 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010573 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010574
Larry Hastings9cf065c2012-06-22 16:30:09 -070010575 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10576 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010577
Larry Hastings9cf065c2012-06-22 16:30:09 -070010578 for (i = 0; ; i++) {
10579 void *ptr;
10580 ssize_t result;
10581 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10582 Py_ssize_t buffer_size = buffer_sizes[i];
10583 if (!buffer_size) {
10584 path_error("getxattr", &path);
10585 goto exit;
10586 }
10587 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10588 if (!buffer)
10589 goto exit;
10590 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010591
Larry Hastings9cf065c2012-06-22 16:30:09 -070010592 Py_BEGIN_ALLOW_THREADS;
10593 if (path.fd >= 0)
10594 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10595 else if (follow_symlinks)
10596 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10597 else
10598 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10599 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010600
Larry Hastings9cf065c2012-06-22 16:30:09 -070010601 if (result < 0) {
10602 Py_DECREF(buffer);
10603 buffer = NULL;
10604 if (errno == ERANGE)
10605 continue;
10606 path_error("getxattr", &path);
10607 goto exit;
10608 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010609
Larry Hastings9cf065c2012-06-22 16:30:09 -070010610 if (result != buffer_size) {
10611 /* Can only shrink. */
10612 _PyBytes_Resize(&buffer, result);
10613 }
10614 break;
10615 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010616
Larry Hastings9cf065c2012-06-22 16:30:09 -070010617exit:
10618 path_cleanup(&path);
10619 path_cleanup(&attribute);
10620 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010621}
10622
10623PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010624"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10625Set extended attribute attribute on path to value.\n\
10626path may be either a string or an open file descriptor.\n\
10627If follow_symlinks is False, and the last element of the path is a symbolic\n\
10628 link, setxattr will modify the symbolic link itself instead of the file\n\
10629 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010630
10631static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010632posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010633{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010634 path_t path;
10635 path_t attribute;
10636 Py_buffer value;
10637 int flags = 0;
10638 int follow_symlinks = 1;
10639 int result;
10640 PyObject *return_value = NULL;
10641 static char *keywords[] = {"path", "attribute", "value",
10642 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010643
Larry Hastings9cf065c2012-06-22 16:30:09 -070010644 memset(&path, 0, sizeof(path));
10645 path.allow_fd = 1;
10646 memset(&attribute, 0, sizeof(attribute));
10647 memset(&value, 0, sizeof(value));
10648 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10649 keywords,
10650 path_converter, &path,
10651 path_converter, &attribute,
10652 &value, &flags,
10653 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010654 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010655
10656 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10657 goto exit;
10658
Benjamin Peterson799bd802011-08-31 22:15:17 -040010659 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010660 if (path.fd > -1)
10661 result = fsetxattr(path.fd, attribute.narrow,
10662 value.buf, value.len, flags);
10663 else if (follow_symlinks)
10664 result = setxattr(path.narrow, attribute.narrow,
10665 value.buf, value.len, flags);
10666 else
10667 result = lsetxattr(path.narrow, attribute.narrow,
10668 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010669 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010670
Larry Hastings9cf065c2012-06-22 16:30:09 -070010671 if (result) {
10672 return_value = path_error("setxattr", &path);
10673 goto exit;
10674 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010675
Larry Hastings9cf065c2012-06-22 16:30:09 -070010676 return_value = Py_None;
10677 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010678
Larry Hastings9cf065c2012-06-22 16:30:09 -070010679exit:
10680 path_cleanup(&path);
10681 path_cleanup(&attribute);
10682 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010683
Larry Hastings9cf065c2012-06-22 16:30:09 -070010684 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010685}
10686
10687PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010688"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10689Remove extended attribute attribute on path.\n\
10690path may be either a string or an open file descriptor.\n\
10691If follow_symlinks is False, and the last element of the path is a symbolic\n\
10692 link, removexattr will modify the symbolic link itself instead of the file\n\
10693 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010694
10695static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010696posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010697{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010698 path_t path;
10699 path_t attribute;
10700 int follow_symlinks = 1;
10701 int result;
10702 PyObject *return_value = NULL;
10703 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010704
Larry Hastings9cf065c2012-06-22 16:30:09 -070010705 memset(&path, 0, sizeof(path));
10706 memset(&attribute, 0, sizeof(attribute));
10707 path.allow_fd = 1;
10708 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10709 keywords,
10710 path_converter, &path,
10711 path_converter, &attribute,
10712 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010713 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010714
10715 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10716 goto exit;
10717
Benjamin Peterson799bd802011-08-31 22:15:17 -040010718 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010719 if (path.fd > -1)
10720 result = fremovexattr(path.fd, attribute.narrow);
10721 else if (follow_symlinks)
10722 result = removexattr(path.narrow, attribute.narrow);
10723 else
10724 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010725 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010726
Larry Hastings9cf065c2012-06-22 16:30:09 -070010727 if (result) {
10728 return_value = path_error("removexattr", &path);
10729 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010730 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010731
Larry Hastings9cf065c2012-06-22 16:30:09 -070010732 return_value = Py_None;
10733 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010734
Larry Hastings9cf065c2012-06-22 16:30:09 -070010735exit:
10736 path_cleanup(&path);
10737 path_cleanup(&attribute);
10738
10739 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010740}
10741
10742PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010743"listxattr(path='.', *, follow_symlinks=True)\n\n\
10744Return a list of extended attributes on path.\n\
10745\n\
10746path may be either None, a string, or an open file descriptor.\n\
10747if path is None, listxattr will examine the current directory.\n\
10748If follow_symlinks is False, and the last element of the path is a symbolic\n\
10749 link, listxattr will examine the symbolic link itself instead of the file\n\
10750 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010751
10752static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010753posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010754{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010755 path_t path;
10756 int follow_symlinks = 1;
10757 Py_ssize_t i;
10758 PyObject *result = NULL;
10759 char *buffer = NULL;
10760 char *name;
10761 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010762
Larry Hastings9cf065c2012-06-22 16:30:09 -070010763 memset(&path, 0, sizeof(path));
10764 path.allow_fd = 1;
10765 path.fd = -1;
10766 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10767 path_converter, &path,
10768 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010769 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010770
Larry Hastings9cf065c2012-06-22 16:30:09 -070010771 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10772 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010773
Larry Hastings9cf065c2012-06-22 16:30:09 -070010774 name = path.narrow ? path.narrow : ".";
10775 for (i = 0; ; i++) {
10776 char *start, *trace, *end;
10777 ssize_t length;
10778 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10779 Py_ssize_t buffer_size = buffer_sizes[i];
10780 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010781 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010782 path_error("listxattr", &path);
10783 break;
10784 }
10785 buffer = PyMem_MALLOC(buffer_size);
10786 if (!buffer) {
10787 PyErr_NoMemory();
10788 break;
10789 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010790
Larry Hastings9cf065c2012-06-22 16:30:09 -070010791 Py_BEGIN_ALLOW_THREADS;
10792 if (path.fd > -1)
10793 length = flistxattr(path.fd, buffer, buffer_size);
10794 else if (follow_symlinks)
10795 length = listxattr(name, buffer, buffer_size);
10796 else
10797 length = llistxattr(name, buffer, buffer_size);
10798 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010799
Larry Hastings9cf065c2012-06-22 16:30:09 -070010800 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010801 if (errno == ERANGE) {
10802 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010803 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010804 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010805 }
Larry Hastings9cf065c2012-06-22 16:30:09 -070010806 path_error("listxattr", &path);
10807 break;
10808 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010809
Larry Hastings9cf065c2012-06-22 16:30:09 -070010810 result = PyList_New(0);
10811 if (!result) {
10812 goto exit;
10813 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010814
Larry Hastings9cf065c2012-06-22 16:30:09 -070010815 end = buffer + length;
10816 for (trace = start = buffer; trace != end; trace++) {
10817 if (!*trace) {
10818 int error;
10819 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10820 trace - start);
10821 if (!attribute) {
10822 Py_DECREF(result);
10823 result = NULL;
10824 goto exit;
10825 }
10826 error = PyList_Append(result, attribute);
10827 Py_DECREF(attribute);
10828 if (error) {
10829 Py_DECREF(result);
10830 result = NULL;
10831 goto exit;
10832 }
10833 start = trace + 1;
10834 }
10835 }
10836 break;
10837 }
10838exit:
10839 path_cleanup(&path);
10840 if (buffer)
10841 PyMem_FREE(buffer);
10842 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010843}
10844
Benjamin Peterson9428d532011-09-14 11:45:52 -040010845#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010846
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010847
Georg Brandl2fb477c2012-02-21 00:33:36 +010010848PyDoc_STRVAR(posix_urandom__doc__,
10849"urandom(n) -> str\n\n\
10850Return n random bytes suitable for cryptographic use.");
10851
10852static PyObject *
10853posix_urandom(PyObject *self, PyObject *args)
10854{
10855 Py_ssize_t size;
10856 PyObject *result;
10857 int ret;
10858
10859 /* Read arguments */
10860 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10861 return NULL;
10862 if (size < 0)
10863 return PyErr_Format(PyExc_ValueError,
10864 "negative argument not allowed");
10865 result = PyBytes_FromStringAndSize(NULL, size);
10866 if (result == NULL)
10867 return NULL;
10868
10869 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10870 PyBytes_GET_SIZE(result));
10871 if (ret == -1) {
10872 Py_DECREF(result);
10873 return NULL;
10874 }
10875 return result;
10876}
10877
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010878/* Terminal size querying */
10879
10880static PyTypeObject TerminalSizeType;
10881
10882PyDoc_STRVAR(TerminalSize_docstring,
10883 "A tuple of (columns, lines) for holding terminal window size");
10884
10885static PyStructSequence_Field TerminalSize_fields[] = {
10886 {"columns", "width of the terminal window in characters"},
10887 {"lines", "height of the terminal window in characters"},
10888 {NULL, NULL}
10889};
10890
10891static PyStructSequence_Desc TerminalSize_desc = {
10892 "os.terminal_size",
10893 TerminalSize_docstring,
10894 TerminalSize_fields,
10895 2,
10896};
10897
10898#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10899PyDoc_STRVAR(termsize__doc__,
10900 "Return the size of the terminal window as (columns, lines).\n" \
10901 "\n" \
10902 "The optional argument fd (default standard output) specifies\n" \
10903 "which file descriptor should be queried.\n" \
10904 "\n" \
10905 "If the file descriptor is not connected to a terminal, an OSError\n" \
10906 "is thrown.\n" \
10907 "\n" \
10908 "This function will only be defined if an implementation is\n" \
10909 "available for this system.\n" \
10910 "\n" \
10911 "shutil.get_terminal_size is the high-level function which should \n" \
10912 "normally be used, os.get_terminal_size is the low-level implementation.");
10913
10914static PyObject*
10915get_terminal_size(PyObject *self, PyObject *args)
10916{
10917 int columns, lines;
10918 PyObject *termsize;
10919
10920 int fd = fileno(stdout);
10921 /* Under some conditions stdout may not be connected and
10922 * fileno(stdout) may point to an invalid file descriptor. For example
10923 * GUI apps don't have valid standard streams by default.
10924 *
10925 * If this happens, and the optional fd argument is not present,
10926 * the ioctl below will fail returning EBADF. This is what we want.
10927 */
10928
10929 if (!PyArg_ParseTuple(args, "|i", &fd))
10930 return NULL;
10931
10932#ifdef TERMSIZE_USE_IOCTL
10933 {
10934 struct winsize w;
10935 if (ioctl(fd, TIOCGWINSZ, &w))
10936 return PyErr_SetFromErrno(PyExc_OSError);
10937 columns = w.ws_col;
10938 lines = w.ws_row;
10939 }
10940#endif /* TERMSIZE_USE_IOCTL */
10941
10942#ifdef TERMSIZE_USE_CONIO
10943 {
10944 DWORD nhandle;
10945 HANDLE handle;
10946 CONSOLE_SCREEN_BUFFER_INFO csbi;
10947 switch (fd) {
10948 case 0: nhandle = STD_INPUT_HANDLE;
10949 break;
10950 case 1: nhandle = STD_OUTPUT_HANDLE;
10951 break;
10952 case 2: nhandle = STD_ERROR_HANDLE;
10953 break;
10954 default:
10955 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10956 }
10957 handle = GetStdHandle(nhandle);
10958 if (handle == NULL)
10959 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10960 if (handle == INVALID_HANDLE_VALUE)
10961 return PyErr_SetFromWindowsErr(0);
10962
10963 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10964 return PyErr_SetFromWindowsErr(0);
10965
10966 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10967 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10968 }
10969#endif /* TERMSIZE_USE_CONIO */
10970
10971 termsize = PyStructSequence_New(&TerminalSizeType);
10972 if (termsize == NULL)
10973 return NULL;
10974 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10975 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10976 if (PyErr_Occurred()) {
10977 Py_DECREF(termsize);
10978 return NULL;
10979 }
10980 return termsize;
10981}
10982#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10983
10984
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010985static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010986 {"access", (PyCFunction)posix_access,
10987 METH_VARARGS | METH_KEYWORDS,
10988 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010989#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010991#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010992 {"chdir", (PyCFunction)posix_chdir,
10993 METH_VARARGS | METH_KEYWORDS,
10994 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010995#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010996 {"chflags", (PyCFunction)posix_chflags,
10997 METH_VARARGS | METH_KEYWORDS,
10998 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010999#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011000 {"chmod", (PyCFunction)posix_chmod,
11001 METH_VARARGS | METH_KEYWORDS,
11002 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011003#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011005#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011006#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 {"chown", (PyCFunction)posix_chown,
11008 METH_VARARGS | METH_KEYWORDS,
11009 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011010#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000011011#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000011012 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011013#endif /* HAVE_LCHMOD */
11014#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011015 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000011016#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000011017#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000011018 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000011019#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011020#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011021 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000011022#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000011023#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000011024 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000011025#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011026#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000011027 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011028#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011029#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000011030 {"getcwd", (PyCFunction)posix_getcwd_unicode,
11031 METH_NOARGS, posix_getcwd__doc__},
11032 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
11033 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011034#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070011035#if defined(HAVE_LINK) || defined(MS_WINDOWS)
11036 {"link", (PyCFunction)posix_link,
11037 METH_VARARGS | METH_KEYWORDS,
11038 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011039#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011040 {"listdir", (PyCFunction)posix_listdir,
11041 METH_VARARGS | METH_KEYWORDS,
11042 posix_listdir__doc__},
11043 {"lstat", (PyCFunction)posix_lstat,
11044 METH_VARARGS | METH_KEYWORDS,
11045 posix_lstat__doc__},
11046 {"mkdir", (PyCFunction)posix_mkdir,
11047 METH_VARARGS | METH_KEYWORDS,
11048 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011049#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000011050 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000011051#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011052#ifdef HAVE_GETPRIORITY
11053 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
11054#endif /* HAVE_GETPRIORITY */
11055#ifdef HAVE_SETPRIORITY
11056 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
11057#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011058#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070011059 {"readlink", (PyCFunction)posix_readlink,
11060 METH_VARARGS | METH_KEYWORDS,
11061 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011062#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000011063#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011064 {"readlink", (PyCFunction)win_readlink,
11065 METH_VARARGS | METH_KEYWORDS,
11066 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000011067#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011068 {"rename", (PyCFunction)posix_rename,
11069 METH_VARARGS | METH_KEYWORDS,
11070 posix_rename__doc__},
11071 {"replace", (PyCFunction)posix_replace,
11072 METH_VARARGS | METH_KEYWORDS,
11073 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070011074 {"rmdir", (PyCFunction)posix_rmdir,
11075 METH_VARARGS | METH_KEYWORDS,
11076 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011077 {"stat", (PyCFunction)posix_stat,
11078 METH_VARARGS | METH_KEYWORDS,
11079 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011080 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011081#if defined(HAVE_SYMLINK)
11082 {"symlink", (PyCFunction)posix_symlink,
11083 METH_VARARGS | METH_KEYWORDS,
11084 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000011085#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000011086#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011088#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011089 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011090#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000011091 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011092#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011093 {"unlink", (PyCFunction)posix_unlink,
11094 METH_VARARGS | METH_KEYWORDS,
11095 posix_unlink__doc__},
11096 {"remove", (PyCFunction)posix_unlink,
11097 METH_VARARGS | METH_KEYWORDS,
11098 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070011099 {"utime", (PyCFunction)posix_utime,
11100 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000011101#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011103#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000011104 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011105#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070011107 {"execve", (PyCFunction)posix_execve,
11108 METH_VARARGS | METH_KEYWORDS,
11109 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000011110#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000011111#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
11113 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000011114#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
11116 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000011117#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000011118#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011119#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000011121#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011122#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011124#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011125#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011126#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011127 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
11128 {"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 +020011129#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011130#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011131 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011132#endif
11133#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011134 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011135#endif
11136#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011137 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011138#endif
11139#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011140 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011141#endif
11142#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011143 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050011144#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011145 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050011146#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011147 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
11148 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
11149#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020011150#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011151#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000011153#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000011154#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000011156#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000011157#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000011159#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011160#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000011162#endif /* HAVE_GETEUID */
11163#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011165#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020011166#ifdef HAVE_GETGROUPLIST
11167 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
11168#endif
Fred Drakec9680921999-12-13 16:37:25 +000011169#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011171#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000011173#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011174 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011175#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011176#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000011177 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011178#endif /* HAVE_GETPPID */
11179#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011180 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011181#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011182#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011183 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011184#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011185#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011186 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011187#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011188#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011189 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011190#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011191#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011192 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011193#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011194#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011195 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11196 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011197#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011198#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011200#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011201#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011202 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011203#endif /* HAVE_SETEUID */
11204#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011205 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011206#endif /* HAVE_SETEGID */
11207#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011208 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011209#endif /* HAVE_SETREUID */
11210#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011211 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000011212#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011213#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011214 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011215#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011216#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011217 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011218#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011219#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011220 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011221#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011222#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011224#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011225#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011227#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011228#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011230#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011231#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011232 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011233#endif /* HAVE_WAIT3 */
11234#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011235 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011236#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011237#if defined(HAVE_WAITID) && !defined(__APPLE__)
11238 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11239#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011240#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011241 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011242#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011243#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011244 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011245#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011246#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011248#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011249#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011250 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011251#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011252#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011254#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011255#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011256 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011257#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011258 {"open", (PyCFunction)posix_open,\
11259 METH_VARARGS | METH_KEYWORDS,
11260 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11262 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11263 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11264 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11265 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011266#ifdef HAVE_LOCKF
11267 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11268#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11270 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011271#ifdef HAVE_READV
11272 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11273#endif
11274#ifdef HAVE_PREAD
11275 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11276#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011278#ifdef HAVE_WRITEV
11279 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11280#endif
11281#ifdef HAVE_PWRITE
11282 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11283#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011284#ifdef HAVE_SENDFILE
11285 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11286 posix_sendfile__doc__},
11287#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011288 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011290#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011292#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011293#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011294 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011295#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011296#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011297 {"mkfifo", (PyCFunction)posix_mkfifo,
11298 METH_VARARGS | METH_KEYWORDS,
11299 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011300#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011301#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011302 {"mknod", (PyCFunction)posix_mknod,
11303 METH_VARARGS | METH_KEYWORDS,
11304 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011305#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011306#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11308 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11309 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011310#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011311#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011312 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011313#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011314#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011315 {"truncate", (PyCFunction)posix_truncate,
11316 METH_VARARGS | METH_KEYWORDS,
11317 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011318#endif
11319#ifdef HAVE_POSIX_FALLOCATE
11320 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11321#endif
11322#ifdef HAVE_POSIX_FADVISE
11323 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11324#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011325#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011326 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011327#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011328#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011329 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011330#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011331 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011332#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011333 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011334#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011335#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011336 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011337#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011338#ifdef HAVE_SYNC
11339 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11340#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011341#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011342 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011343#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011344#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011345#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011346 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011347#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011348#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011349 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011350#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011351#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011352 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011353#endif /* WIFSTOPPED */
11354#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011355 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011356#endif /* WIFSIGNALED */
11357#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011358 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011359#endif /* WIFEXITED */
11360#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011361 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011362#endif /* WEXITSTATUS */
11363#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011364 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011365#endif /* WTERMSIG */
11366#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011367 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011368#endif /* WSTOPSIG */
11369#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011370#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011371 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011372#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011373#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011374 {"statvfs", (PyCFunction)posix_statvfs,
11375 METH_VARARGS | METH_KEYWORDS,
11376 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011377#endif
Fred Drakec9680921999-12-13 16:37:25 +000011378#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011379 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011380#endif
11381#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011382 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011383#endif
11384#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011385 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011386#endif
11387#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011388 {"pathconf", (PyCFunction)posix_pathconf,
11389 METH_VARARGS | METH_KEYWORDS,
11390 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011391#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011392 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011393#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011394 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011395 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011396 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011397 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011398 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011399#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011400#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011401 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011402#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011403 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011404#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011406#endif
11407#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011409#endif
11410#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011412#endif
11413#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011415#endif
11416
Benjamin Peterson9428d532011-09-14 11:45:52 -040011417#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011418 {"setxattr", (PyCFunction)posix_setxattr,
11419 METH_VARARGS | METH_KEYWORDS,
11420 posix_setxattr__doc__},
11421 {"getxattr", (PyCFunction)posix_getxattr,
11422 METH_VARARGS | METH_KEYWORDS,
11423 posix_getxattr__doc__},
11424 {"removexattr", (PyCFunction)posix_removexattr,
11425 METH_VARARGS | METH_KEYWORDS,
11426 posix_removexattr__doc__},
11427 {"listxattr", (PyCFunction)posix_listxattr,
11428 METH_VARARGS | METH_KEYWORDS,
11429 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011430#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011431#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11432 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11433#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011434 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011435};
11436
11437
Barry Warsaw4a342091996-12-19 23:50:02 +000011438static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011439ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011440{
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011442}
11443
Guido van Rossumd48f2521997-12-05 22:19:34 +000011444#if defined(PYOS_OS2)
11445/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011446static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011447{
11448 APIRET rc;
11449 ULONG values[QSV_MAX+1];
11450 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011451 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011452
11453 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011454 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011455 Py_END_ALLOW_THREADS
11456
11457 if (rc != NO_ERROR) {
11458 os2_error(rc);
11459 return -1;
11460 }
11461
Fred Drake4d1e64b2002-04-15 19:40:07 +000011462 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11463 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11464 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11465 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11466 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11467 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11468 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011469
11470 switch (values[QSV_VERSION_MINOR]) {
11471 case 0: ver = "2.00"; break;
11472 case 10: ver = "2.10"; break;
11473 case 11: ver = "2.11"; break;
11474 case 30: ver = "3.00"; break;
11475 case 40: ver = "4.00"; break;
11476 case 50: ver = "5.00"; break;
11477 default:
Tim Peters885d4572001-11-28 20:27:42 +000011478 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011480 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011481 ver = &tmp[0];
11482 }
11483
11484 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011485 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011486 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011487
11488 /* Add Indicator of Which Drive was Used to Boot the System */
11489 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11490 tmp[1] = ':';
11491 tmp[2] = '\0';
11492
Fred Drake4d1e64b2002-04-15 19:40:07 +000011493 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011494}
11495#endif
11496
Brian Curtin52173d42010-12-02 18:29:18 +000011497#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011498static int
Brian Curtin52173d42010-12-02 18:29:18 +000011499enable_symlink()
11500{
11501 HANDLE tok;
11502 TOKEN_PRIVILEGES tok_priv;
11503 LUID luid;
11504 int meth_idx = 0;
11505
11506 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011507 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011508
11509 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011510 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011511
11512 tok_priv.PrivilegeCount = 1;
11513 tok_priv.Privileges[0].Luid = luid;
11514 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11515
11516 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11517 sizeof(TOKEN_PRIVILEGES),
11518 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011519 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011520
Brian Curtin3b4499c2010-12-28 14:31:47 +000011521 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11522 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011523}
11524#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11525
Barry Warsaw4a342091996-12-19 23:50:02 +000011526static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011527all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011528{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011529#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011531#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011532#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011533 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011534#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011535#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011536 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011537#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011538#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011539 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011540#endif
Fred Drakec9680921999-12-13 16:37:25 +000011541#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011542 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011543#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011544#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011545 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011546#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011547#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011549#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011550#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011551 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011552#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011553#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011554 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011555#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011556#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011557 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011558#endif
11559#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011560 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011561#endif
11562#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011563 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011564#endif
11565#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011566 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011567#endif
11568#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011569 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011570#endif
11571#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011572 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011573#endif
11574#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011575 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011576#endif
11577#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011579#endif
11580#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011581 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011582#endif
11583#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011584 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011585#endif
11586#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011587 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011588#endif
11589#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011590 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011591#endif
11592#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011593 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011594#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011595#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011596 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011597#endif
11598#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011599 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011600#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011601#ifdef O_XATTR
11602 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11603#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011604#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011605 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011606#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011607#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011608 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011609#endif
11610#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011611 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011612#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011613#ifdef O_EXEC
11614 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11615#endif
11616#ifdef O_SEARCH
11617 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11618#endif
11619#ifdef O_TTY_INIT
11620 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11621#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011622#ifdef PRIO_PROCESS
11623 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11624#endif
11625#ifdef PRIO_PGRP
11626 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11627#endif
11628#ifdef PRIO_USER
11629 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11630#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011631#ifdef O_CLOEXEC
11632 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11633#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011634#ifdef O_ACCMODE
11635 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11636#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011637
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011638
Jesus Cea94363612012-06-22 18:32:07 +020011639#ifdef SEEK_HOLE
11640 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11641#endif
11642#ifdef SEEK_DATA
11643 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11644#endif
11645
Tim Peters5aa91602002-01-30 05:46:57 +000011646/* MS Windows */
11647#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011648 /* Don't inherit in child processes. */
11649 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011650#endif
11651#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011652 /* Optimize for short life (keep in memory). */
11653 /* MS forgot to define this one with a non-underscore form too. */
11654 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011655#endif
11656#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011657 /* Automatically delete when last handle is closed. */
11658 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011659#endif
11660#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011661 /* Optimize for random access. */
11662 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011663#endif
11664#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011665 /* Optimize for sequential access. */
11666 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011667#endif
11668
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011669/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011670#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011671 /* Send a SIGIO signal whenever input or output
11672 becomes available on file descriptor */
11673 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011674#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011675#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011676 /* Direct disk access. */
11677 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011678#endif
11679#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011680 /* Must be a directory. */
11681 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011682#endif
11683#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011684 /* Do not follow links. */
11685 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011686#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011687#ifdef O_NOLINKS
11688 /* Fails if link count of the named file is greater than 1 */
11689 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11690#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011691#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011692 /* Do not update the access time. */
11693 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011694#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011695
Victor Stinner8c62be82010-05-06 00:08:46 +000011696 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011697#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011698 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011699#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011700#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011701 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011702#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011703#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011704 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011705#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011706#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011707 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011708#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011709#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011710 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011711#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011712#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011713 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011714#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011715#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011716 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011717#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011718#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011719 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011720#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011721#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011722 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011723#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011724#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011725 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011726#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011727#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011728 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011729#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011730#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011731 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011732#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011733#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011734 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011735#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011736#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011737 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011738#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011739#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011740 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011741#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011742#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011743 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011744#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011745#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011746 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011747#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011748
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011749 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011750#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011751 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011752#endif /* ST_RDONLY */
11753#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011754 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011755#endif /* ST_NOSUID */
11756
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011757 /* FreeBSD sendfile() constants */
11758#ifdef SF_NODISKIO
11759 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11760#endif
11761#ifdef SF_MNOWAIT
11762 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11763#endif
11764#ifdef SF_SYNC
11765 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11766#endif
11767
Ross Lagerwall7807c352011-03-17 20:20:30 +020011768 /* constants for posix_fadvise */
11769#ifdef POSIX_FADV_NORMAL
11770 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11771#endif
11772#ifdef POSIX_FADV_SEQUENTIAL
11773 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11774#endif
11775#ifdef POSIX_FADV_RANDOM
11776 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11777#endif
11778#ifdef POSIX_FADV_NOREUSE
11779 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11780#endif
11781#ifdef POSIX_FADV_WILLNEED
11782 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11783#endif
11784#ifdef POSIX_FADV_DONTNEED
11785 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11786#endif
11787
11788 /* constants for waitid */
11789#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11790 if (ins(d, "P_PID", (long)P_PID)) return -1;
11791 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11792 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11793#endif
11794#ifdef WEXITED
11795 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11796#endif
11797#ifdef WNOWAIT
11798 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11799#endif
11800#ifdef WSTOPPED
11801 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11802#endif
11803#ifdef CLD_EXITED
11804 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11805#endif
11806#ifdef CLD_DUMPED
11807 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11808#endif
11809#ifdef CLD_TRAPPED
11810 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11811#endif
11812#ifdef CLD_CONTINUED
11813 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11814#endif
11815
11816 /* constants for lockf */
11817#ifdef F_LOCK
11818 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11819#endif
11820#ifdef F_TLOCK
11821 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11822#endif
11823#ifdef F_ULOCK
11824 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11825#endif
11826#ifdef F_TEST
11827 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11828#endif
11829
Guido van Rossum246bc171999-02-01 23:54:31 +000011830#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011831#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011832 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11833 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11834 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11835 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11836 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11837 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11838 if (ins(d, "P_PM", (long)P_PM)) return -1;
11839 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11840 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11841 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11842 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11843 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11844 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11845 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11846 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11847 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11848 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11849 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11850 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11851 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011852#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011853 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11854 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11855 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11856 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11857 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011858#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011859#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011860
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011861#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011862 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011863 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11864 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11865#ifdef SCHED_SPORADIC
Benjamin Peterson46375382014-01-10 09:22:40 -060011866 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011867#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011868#ifdef SCHED_BATCH
11869 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11870#endif
11871#ifdef SCHED_IDLE
11872 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11873#endif
11874#ifdef SCHED_RESET_ON_FORK
11875 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11876#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011877#ifdef SCHED_SYS
11878 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11879#endif
11880#ifdef SCHED_IA
11881 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11882#endif
11883#ifdef SCHED_FSS
11884 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11885#endif
11886#ifdef SCHED_FX
11887 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11888#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011889#endif
11890
Benjamin Peterson9428d532011-09-14 11:45:52 -040011891#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011892 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11893 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11894 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11895#endif
11896
Victor Stinner8b905bd2011-10-25 13:34:04 +020011897#ifdef RTLD_LAZY
11898 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11899#endif
11900#ifdef RTLD_NOW
11901 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11902#endif
11903#ifdef RTLD_GLOBAL
11904 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11905#endif
11906#ifdef RTLD_LOCAL
11907 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11908#endif
11909#ifdef RTLD_NODELETE
11910 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11911#endif
11912#ifdef RTLD_NOLOAD
11913 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11914#endif
11915#ifdef RTLD_DEEPBIND
11916 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11917#endif
11918
Guido van Rossumd48f2521997-12-05 22:19:34 +000011919#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011920 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011922 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011923}
11924
11925
Tim Peters5aa91602002-01-30 05:46:57 +000011926#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011927#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011928#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011929
11930#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011931#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011932#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011933
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011934#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011935#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011936#define MODNAME "posix"
11937#endif
11938
Martin v. Löwis1a214512008-06-11 05:26:20 +000011939static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011940 PyModuleDef_HEAD_INIT,
11941 MODNAME,
11942 posix__doc__,
11943 -1,
11944 posix_methods,
11945 NULL,
11946 NULL,
11947 NULL,
11948 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011949};
11950
11951
Larry Hastings9cf065c2012-06-22 16:30:09 -070011952static char *have_functions[] = {
11953
11954#ifdef HAVE_FACCESSAT
11955 "HAVE_FACCESSAT",
11956#endif
11957
11958#ifdef HAVE_FCHDIR
11959 "HAVE_FCHDIR",
11960#endif
11961
11962#ifdef HAVE_FCHMOD
11963 "HAVE_FCHMOD",
11964#endif
11965
11966#ifdef HAVE_FCHMODAT
11967 "HAVE_FCHMODAT",
11968#endif
11969
11970#ifdef HAVE_FCHOWN
11971 "HAVE_FCHOWN",
11972#endif
11973
Larry Hastings00964ed2013-08-12 13:49:30 -040011974#ifdef HAVE_FCHOWNAT
11975 "HAVE_FCHOWNAT",
11976#endif
11977
Larry Hastings9cf065c2012-06-22 16:30:09 -070011978#ifdef HAVE_FEXECVE
11979 "HAVE_FEXECVE",
11980#endif
11981
11982#ifdef HAVE_FDOPENDIR
11983 "HAVE_FDOPENDIR",
11984#endif
11985
Georg Brandl306336b2012-06-24 12:55:33 +020011986#ifdef HAVE_FPATHCONF
11987 "HAVE_FPATHCONF",
11988#endif
11989
Larry Hastings9cf065c2012-06-22 16:30:09 -070011990#ifdef HAVE_FSTATAT
11991 "HAVE_FSTATAT",
11992#endif
11993
11994#ifdef HAVE_FSTATVFS
11995 "HAVE_FSTATVFS",
11996#endif
11997
Georg Brandl306336b2012-06-24 12:55:33 +020011998#ifdef HAVE_FTRUNCATE
11999 "HAVE_FTRUNCATE",
12000#endif
12001
Larry Hastings9cf065c2012-06-22 16:30:09 -070012002#ifdef HAVE_FUTIMENS
12003 "HAVE_FUTIMENS",
12004#endif
12005
12006#ifdef HAVE_FUTIMES
12007 "HAVE_FUTIMES",
12008#endif
12009
12010#ifdef HAVE_FUTIMESAT
12011 "HAVE_FUTIMESAT",
12012#endif
12013
12014#ifdef HAVE_LINKAT
12015 "HAVE_LINKAT",
12016#endif
12017
12018#ifdef HAVE_LCHFLAGS
12019 "HAVE_LCHFLAGS",
12020#endif
12021
12022#ifdef HAVE_LCHMOD
12023 "HAVE_LCHMOD",
12024#endif
12025
12026#ifdef HAVE_LCHOWN
12027 "HAVE_LCHOWN",
12028#endif
12029
12030#ifdef HAVE_LSTAT
12031 "HAVE_LSTAT",
12032#endif
12033
12034#ifdef HAVE_LUTIMES
12035 "HAVE_LUTIMES",
12036#endif
12037
12038#ifdef HAVE_MKDIRAT
12039 "HAVE_MKDIRAT",
12040#endif
12041
12042#ifdef HAVE_MKFIFOAT
12043 "HAVE_MKFIFOAT",
12044#endif
12045
12046#ifdef HAVE_MKNODAT
12047 "HAVE_MKNODAT",
12048#endif
12049
12050#ifdef HAVE_OPENAT
12051 "HAVE_OPENAT",
12052#endif
12053
12054#ifdef HAVE_READLINKAT
12055 "HAVE_READLINKAT",
12056#endif
12057
12058#ifdef HAVE_RENAMEAT
12059 "HAVE_RENAMEAT",
12060#endif
12061
12062#ifdef HAVE_SYMLINKAT
12063 "HAVE_SYMLINKAT",
12064#endif
12065
12066#ifdef HAVE_UNLINKAT
12067 "HAVE_UNLINKAT",
12068#endif
12069
12070#ifdef HAVE_UTIMENSAT
12071 "HAVE_UTIMENSAT",
12072#endif
12073
12074#ifdef MS_WINDOWS
12075 "MS_WINDOWS",
12076#endif
12077
12078 NULL
12079};
12080
12081
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012082PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012083INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012084{
Victor Stinner8c62be82010-05-06 00:08:46 +000012085 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012086 PyObject *list;
12087 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012088
Brian Curtin52173d42010-12-02 18:29:18 +000012089#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012090 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012091#endif
12092
Victor Stinner8c62be82010-05-06 00:08:46 +000012093 m = PyModule_Create(&posixmodule);
12094 if (m == NULL)
12095 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012096
Victor Stinner8c62be82010-05-06 00:08:46 +000012097 /* Initialize environ dictionary */
12098 v = convertenviron();
12099 Py_XINCREF(v);
12100 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12101 return NULL;
12102 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012103
Victor Stinner8c62be82010-05-06 00:08:46 +000012104 if (all_ins(m))
12105 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012106
Victor Stinner8c62be82010-05-06 00:08:46 +000012107 if (setup_confname_tables(m))
12108 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012109
Victor Stinner8c62be82010-05-06 00:08:46 +000012110 Py_INCREF(PyExc_OSError);
12111 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012112
Guido van Rossumb3d39562000-01-31 18:41:26 +000012113#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012114 if (posix_putenv_garbage == NULL)
12115 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012116#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012117
Victor Stinner8c62be82010-05-06 00:08:46 +000012118 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012119#if defined(HAVE_WAITID) && !defined(__APPLE__)
12120 waitid_result_desc.name = MODNAME ".waitid_result";
12121 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
12122#endif
12123
Victor Stinner8c62be82010-05-06 00:08:46 +000012124 stat_result_desc.name = MODNAME ".stat_result";
12125 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12126 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12127 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
12128 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
12129 structseq_new = StatResultType.tp_new;
12130 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012131
Victor Stinner8c62be82010-05-06 00:08:46 +000012132 statvfs_result_desc.name = MODNAME ".statvfs_result";
12133 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012134#ifdef NEED_TICKS_PER_SECOND
12135# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012136 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012137# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012138 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012139# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012140 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012141# endif
12142#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012143
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012144#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012145 sched_param_desc.name = MODNAME ".sched_param";
12146 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
12147 SchedParamType.tp_new = sched_param_new;
12148#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012149
12150 /* initialize TerminalSize_info */
12151 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000012152 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012153#if defined(HAVE_WAITID) && !defined(__APPLE__)
12154 Py_INCREF((PyObject*) &WaitidResultType);
12155 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12156#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012157 Py_INCREF((PyObject*) &StatResultType);
12158 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12159 Py_INCREF((PyObject*) &StatVFSResultType);
12160 PyModule_AddObject(m, "statvfs_result",
12161 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012162
12163#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012164 Py_INCREF(&SchedParamType);
12165 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012166#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012167
Larry Hastings605a62d2012-06-24 04:33:36 -070012168 times_result_desc.name = MODNAME ".times_result";
12169 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
12170 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12171
12172 uname_result_desc.name = MODNAME ".uname_result";
12173 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
12174 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12175
Thomas Wouters477c8d52006-05-27 19:21:47 +000012176#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012177 /*
12178 * Step 2 of weak-linking support on Mac OS X.
12179 *
12180 * The code below removes functions that are not available on the
12181 * currently active platform.
12182 *
12183 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012184 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012185 * OSX 10.4.
12186 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012187#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012188 if (fstatvfs == NULL) {
12189 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12190 return NULL;
12191 }
12192 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012193#endif /* HAVE_FSTATVFS */
12194
12195#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012196 if (statvfs == NULL) {
12197 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12198 return NULL;
12199 }
12200 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012201#endif /* HAVE_STATVFS */
12202
12203# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012204 if (lchown == NULL) {
12205 if (PyObject_DelAttrString(m, "lchown") == -1) {
12206 return NULL;
12207 }
12208 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012209#endif /* HAVE_LCHOWN */
12210
12211
12212#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012213
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012214 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012215 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12216
Larry Hastings6fe20b32012-04-19 15:07:49 -070012217 billion = PyLong_FromLong(1000000000);
12218 if (!billion)
12219 return NULL;
12220
Larry Hastings9cf065c2012-06-22 16:30:09 -070012221 /* suppress "function not used" warnings */
12222 {
12223 int ignored;
12224 fd_specified("", -1);
12225 follow_symlinks_specified("", 1);
12226 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12227 dir_fd_converter(Py_None, &ignored);
12228 dir_fd_unavailable(Py_None, &ignored);
12229 }
12230
12231 /*
12232 * provide list of locally available functions
12233 * so os.py can populate support_* lists
12234 */
12235 list = PyList_New(0);
12236 if (!list)
12237 return NULL;
12238 for (trace = have_functions; *trace; trace++) {
12239 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12240 if (!unicode)
12241 return NULL;
12242 if (PyList_Append(list, unicode))
12243 return NULL;
12244 Py_DECREF(unicode);
12245 }
12246 PyModule_AddObject(m, "_have_functions", list);
12247
12248 initialized = 1;
12249
Victor Stinner8c62be82010-05-06 00:08:46 +000012250 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012251
Guido van Rossumb6775db1994-08-01 11:34:53 +000012252}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012253
12254#ifdef __cplusplus
12255}
12256#endif