blob: 91352d4d4c488f8dd1d5b95fbfce46c209960643 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
31#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000032
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020034# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000036#endif /* defined(__VMS) */
37
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000038#ifdef __cplusplus
39extern "C" {
40#endif
41
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000042PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000043"This module provides access to operating system functionality that is\n\
44standardized by the C Standard and the POSIX standard (a thinly\n\
45disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000046corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000048
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000049#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020050#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#define INCL_DOS
52#define INCL_DOSERRORS
53#define INCL_DOSPROCESS
54#define INCL_NOPMAPI
55#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000056#if defined(PYCC_GCC)
57#include <ctype.h>
58#include <io.h>
59#include <stdio.h>
60#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000061#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000062#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000063#endif
64
Ross Lagerwall4d076da2011-03-18 06:56:53 +020065#ifdef HAVE_SYS_UIO_H
66#include <sys/uio.h>
67#endif
68
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000070#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000071#endif /* HAVE_SYS_TYPES_H */
72
73#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000076
Guido van Rossum36bc6801995-06-14 22:54:23 +000077#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000078#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000079#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000080
Thomas Wouters0e3f5912006-08-11 14:57:12 +000081#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000082#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000083#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000084
Guido van Rossumb6775db1994-08-01 11:34:53 +000085#ifdef HAVE_FCNTL_H
86#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000087#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000088
Guido van Rossuma6535fd2001-10-18 19:44:10 +000089#ifdef HAVE_GRP_H
90#include <grp.h>
91#endif
92
Barry Warsaw5676bd12003-01-07 20:57:09 +000093#ifdef HAVE_SYSEXITS_H
94#include <sysexits.h>
95#endif /* HAVE_SYSEXITS_H */
96
Anthony Baxter8a560de2004-10-13 15:30:56 +000097#ifdef HAVE_SYS_LOADAVG_H
98#include <sys/loadavg.h>
99#endif
100
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +0000101#ifdef HAVE_LANGINFO_H
102#include <langinfo.h>
103#endif
104
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000105#ifdef HAVE_SYS_SENDFILE_H
106#include <sys/sendfile.h>
107#endif
108
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500109#ifdef HAVE_SCHED_H
110#include <sched.h>
111#endif
112
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500113#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500114#undef HAVE_SCHED_SETAFFINITY
115#endif
116
Benjamin Peterson9428d532011-09-14 11:45:52 -0400117#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
118#define USE_XATTRS
119#endif
120
121#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400122#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400123#endif
124
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000125#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
126#ifdef HAVE_SYS_SOCKET_H
127#include <sys/socket.h>
128#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000129#endif
130
Victor Stinner8b905bd2011-10-25 13:34:04 +0200131#ifdef HAVE_DLFCN_H
132#include <dlfcn.h>
133#endif
134
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100135#if defined(MS_WINDOWS)
136# define TERMSIZE_USE_CONIO
137#elif defined(HAVE_SYS_IOCTL_H)
138# include <sys/ioctl.h>
139# if defined(HAVE_TERMIOS_H)
140# include <termios.h>
141# endif
142# if defined(TIOCGWINSZ)
143# define TERMSIZE_USE_IOCTL
144# endif
145#endif /* MS_WINDOWS */
146
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000147/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000148/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000149#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#include <process.h>
151#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_GETCWD 1
154#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#if defined(__OS2__)
157#define HAVE_EXECV 1
158#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000159#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#include <process.h>
161#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000163#define HAVE_EXECV 1
164#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#define HAVE_OPENDIR 1
166#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#define HAVE_WAIT 1
169#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000170#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000171#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000172#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000173#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#define HAVE_EXECV 1
176#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000177#define HAVE_SYSTEM 1
178#define HAVE_CWAIT 1
179#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000180#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000181#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000182#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
183/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000184#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185/* Unix functions that the configure script doesn't check for */
186#define HAVE_EXECV 1
187#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000188#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000189#define HAVE_FORK1 1
190#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000191#define HAVE_GETCWD 1
192#define HAVE_GETEGID 1
193#define HAVE_GETEUID 1
194#define HAVE_GETGID 1
195#define HAVE_GETPPID 1
196#define HAVE_GETUID 1
197#define HAVE_KILL 1
198#define HAVE_OPENDIR 1
199#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000200#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000202#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000203#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#endif /* _MSC_VER */
205#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000206#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000207#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000208
Victor Stinnera2f7c002012-02-08 03:36:25 +0100209
210
211
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000213
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000214#if defined(__sgi)&&_COMPILER_VERSION>=700
215/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
216 (default) */
217extern char *ctermid_r(char *);
218#endif
219
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000220#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000221#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000222extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000224#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000229#endif
230#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000231extern int chdir(char *);
232extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000233#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int chdir(const char *);
235extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000236#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000237#ifdef __BORLANDC__
238extern int chmod(const char *, int);
239#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000241#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000242/*#ifdef HAVE_FCHMOD
243extern int fchmod(int, mode_t);
244#endif*/
245/*#ifdef HAVE_LCHMOD
246extern int lchmod(const char *, mode_t);
247#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000248extern int chown(const char *, uid_t, gid_t);
249extern char *getcwd(char *, int);
250extern char *strerror(int);
251extern int link(const char *, const char *);
252extern int rename(const char *, const char *);
253extern int stat(const char *, struct stat *);
254extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000256extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000257#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000259extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000260#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000262
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000263#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#ifdef HAVE_UTIME_H
266#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000267#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000269#ifdef HAVE_SYS_UTIME_H
270#include <sys/utime.h>
271#define HAVE_UTIME_H /* pretend we do for the rest of this file */
272#endif /* HAVE_SYS_UTIME_H */
273
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#ifdef HAVE_SYS_TIMES_H
275#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000276#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
278#ifdef HAVE_SYS_PARAM_H
279#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000280#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281
282#ifdef HAVE_SYS_UTSNAME_H
283#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000284#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#define NAMLEN(dirent) strlen((dirent)->d_name)
289#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000290#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000291#include <direct.h>
292#define NAMLEN(dirent) strlen((dirent)->d_name)
293#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000295#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000296#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000297#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000298#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000299#endif
300#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000302#endif
303#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000304#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000305#endif
306#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000308#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000309#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311#endif
312#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000313#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314#endif
315#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000316#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000317#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000318#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000319#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000320#endif
321#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000322#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000323#endif
324#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000325#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000326#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000328#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000329#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000330#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000331#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000332#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
333#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000334static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000335#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000336#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000337
Guido van Rossumd48f2521997-12-05 22:19:34 +0000338#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000339#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000340#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341
Tim Petersbc2e10e2002-03-03 23:17:02 +0000342#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000343#if defined(PATH_MAX) && PATH_MAX > 1024
344#define MAXPATHLEN PATH_MAX
345#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000346#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000347#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000348#endif /* MAXPATHLEN */
349
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000350#ifdef UNION_WAIT
351/* Emulate some macros on systems that have a union instead of macros */
352
353#ifndef WIFEXITED
354#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
355#endif
356
357#ifndef WEXITSTATUS
358#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
359#endif
360
361#ifndef WTERMSIG
362#define WTERMSIG(u_wait) ((u_wait).w_termsig)
363#endif
364
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000365#define WAIT_TYPE union wait
366#define WAIT_STATUS_INT(s) (s.w_status)
367
368#else /* !UNION_WAIT */
369#define WAIT_TYPE int
370#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000371#endif /* UNION_WAIT */
372
Greg Wardb48bc172000-03-01 21:51:56 +0000373/* Don't use the "_r" form if we don't need it (also, won't have a
374 prototype for it, at least on Solaris -- maybe others as well?). */
375#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
376#define USE_CTERMID_R
377#endif
378
Fred Drake699f3522000-06-29 21:12:41 +0000379/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000380#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000381#undef FSTAT
382#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000383#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000384# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700385# define LSTAT win32_lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000386# define FSTAT win32_fstat
387# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000388#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000389# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700390# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000391# define FSTAT fstat
392# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000393#endif
394
Tim Peters11b23062003-04-23 02:39:17 +0000395#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000396#include <sys/mkdev.h>
397#else
398#if defined(MAJOR_IN_SYSMACROS)
399#include <sys/sysmacros.h>
400#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000401#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
402#include <sys/mkdev.h>
403#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000404#endif
Fred Drake699f3522000-06-29 21:12:41 +0000405
Larry Hastings9cf065c2012-06-22 16:30:09 -0700406
407#ifdef MS_WINDOWS
408static int
409win32_warn_bytes_api()
410{
411 return PyErr_WarnEx(PyExc_DeprecationWarning,
412 "The Windows bytes API has been deprecated, "
413 "use Unicode filenames instead",
414 1);
415}
416#endif
417
418
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200419#ifndef MS_WINDOWS
420PyObject *
421_PyLong_FromUid(uid_t uid)
422{
423 if (uid == (uid_t)-1)
424 return PyLong_FromLong(-1);
425 return PyLong_FromUnsignedLong(uid);
426}
427
428PyObject *
429_PyLong_FromGid(gid_t gid)
430{
431 if (gid == (gid_t)-1)
432 return PyLong_FromLong(-1);
433 return PyLong_FromUnsignedLong(gid);
434}
435
436int
437_Py_Uid_Converter(PyObject *obj, void *p)
438{
439 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200440 long result;
441 if (PyFloat_Check(obj)) {
442 PyErr_SetString(PyExc_TypeError,
443 "integer argument expected, got float");
444 return 0;
445 }
446 result = PyLong_AsLongAndOverflow(obj, &overflow);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200447 if (overflow < 0)
448 goto OverflowDown;
449 if (!overflow && result == -1) {
450 /* error or -1 */
451 if (PyErr_Occurred())
452 return 0;
453 *(uid_t *)p = (uid_t)-1;
454 }
455 else {
456 /* unsigned uid_t */
457 unsigned long uresult;
458 if (overflow > 0) {
459 uresult = PyLong_AsUnsignedLong(obj);
460 if (PyErr_Occurred()) {
461 if (PyErr_ExceptionMatches(PyExc_OverflowError))
462 goto OverflowUp;
463 return 0;
464 }
465 if ((uid_t)uresult == (uid_t)-1)
466 goto OverflowUp;
467 } else {
468 if (result < 0)
469 goto OverflowDown;
470 uresult = result;
471 }
472 if (sizeof(uid_t) < sizeof(long) &&
473 (unsigned long)(uid_t)uresult != uresult)
474 goto OverflowUp;
475 *(uid_t *)p = (uid_t)uresult;
476 }
477 return 1;
478
479OverflowDown:
480 PyErr_SetString(PyExc_OverflowError,
481 "user id is less than minimum");
482 return 0;
483
484OverflowUp:
485 PyErr_SetString(PyExc_OverflowError,
486 "user id is greater than maximum");
487 return 0;
488}
489
490int
491_Py_Gid_Converter(PyObject *obj, void *p)
492{
493 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200494 long result;
495 if (PyFloat_Check(obj)) {
496 PyErr_SetString(PyExc_TypeError,
497 "integer argument expected, got float");
498 return 0;
499 }
500 result = PyLong_AsLongAndOverflow(obj, &overflow);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200501 if (overflow < 0)
502 goto OverflowDown;
503 if (!overflow && result == -1) {
504 /* error or -1 */
505 if (PyErr_Occurred())
506 return 0;
507 *(gid_t *)p = (gid_t)-1;
508 }
509 else {
510 /* unsigned gid_t */
511 unsigned long uresult;
512 if (overflow > 0) {
513 uresult = PyLong_AsUnsignedLong(obj);
514 if (PyErr_Occurred()) {
515 if (PyErr_ExceptionMatches(PyExc_OverflowError))
516 goto OverflowUp;
517 return 0;
518 }
519 if ((gid_t)uresult == (gid_t)-1)
520 goto OverflowUp;
521 } else {
522 if (result < 0)
523 goto OverflowDown;
524 uresult = result;
525 }
526 if (sizeof(gid_t) < sizeof(long) &&
527 (unsigned long)(gid_t)uresult != uresult)
528 goto OverflowUp;
529 *(gid_t *)p = (gid_t)uresult;
530 }
531 return 1;
532
533OverflowDown:
534 PyErr_SetString(PyExc_OverflowError,
535 "group id is less than minimum");
536 return 0;
537
538OverflowUp:
539 PyErr_SetString(PyExc_OverflowError,
540 "group id is greater than maximum");
541 return 0;
542}
543#endif /* MS_WINDOWS */
544
545
Larry Hastings9cf065c2012-06-22 16:30:09 -0700546#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400547/*
548 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
549 * without the int cast, the value gets interpreted as uint (4291925331),
550 * which doesn't play nicely with all the initializer lines in this file that
551 * look like this:
552 * int dir_fd = DEFAULT_DIR_FD;
553 */
554#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700555#else
556#define DEFAULT_DIR_FD (-100)
557#endif
558
559static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200560_fd_converter(PyObject *o, int *p, const char *allowed)
561{
562 int overflow;
563 long long_value = PyLong_AsLongAndOverflow(o, &overflow);
564 if (PyFloat_Check(o) ||
565 (long_value == -1 && !overflow && PyErr_Occurred())) {
566 PyErr_Clear();
567 PyErr_Format(PyExc_TypeError,
568 "argument should be %s, not %.200s",
569 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700570 return 0;
571 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200572 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700573 PyErr_SetString(PyExc_OverflowError,
574 "signed integer is greater than maximum");
575 return 0;
576 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200577 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700578 PyErr_SetString(PyExc_OverflowError,
579 "signed integer is less than minimum");
580 return 0;
581 }
582 *p = (int)long_value;
583 return 1;
584}
585
586static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200587dir_fd_converter(PyObject *o, void *p)
588{
589 if (o == Py_None) {
590 *(int *)p = DEFAULT_DIR_FD;
591 return 1;
592 }
593 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700594}
595
596
597
598/*
599 * A PyArg_ParseTuple "converter" function
600 * that handles filesystem paths in the manner
601 * preferred by the os module.
602 *
603 * path_converter accepts (Unicode) strings and their
604 * subclasses, and bytes and their subclasses. What
605 * it does with the argument depends on the platform:
606 *
607 * * On Windows, if we get a (Unicode) string we
608 * extract the wchar_t * and return it; if we get
609 * bytes we extract the char * and return that.
610 *
611 * * On all other platforms, strings are encoded
612 * to bytes using PyUnicode_FSConverter, then we
613 * extract the char * from the bytes object and
614 * return that.
615 *
616 * path_converter also optionally accepts signed
617 * integers (representing open file descriptors) instead
618 * of path strings.
619 *
620 * Input fields:
621 * path.nullable
622 * If nonzero, the path is permitted to be None.
623 * path.allow_fd
624 * If nonzero, the path is permitted to be a file handle
625 * (a signed int) instead of a string.
626 * path.function_name
627 * If non-NULL, path_converter will use that as the name
628 * of the function in error messages.
629 * (If path.argument_name is NULL it omits the function name.)
630 * path.argument_name
631 * If non-NULL, path_converter will use that as the name
632 * of the parameter in error messages.
633 * (If path.argument_name is NULL it uses "path".)
634 *
635 * Output fields:
636 * path.wide
637 * Points to the path if it was expressed as Unicode
638 * and was not encoded. (Only used on Windows.)
639 * path.narrow
640 * Points to the path if it was expressed as bytes,
641 * or it was Unicode and was encoded to bytes.
642 * path.fd
643 * Contains a file descriptor if path.accept_fd was true
644 * and the caller provided a signed integer instead of any
645 * sort of string.
646 *
647 * WARNING: if your "path" parameter is optional, and is
648 * unspecified, path_converter will never get called.
649 * So if you set allow_fd, you *MUST* initialize path.fd = -1
650 * yourself!
651 * path.length
652 * The length of the path in characters, if specified as
653 * a string.
654 * path.object
655 * The original object passed in.
656 * path.cleanup
657 * For internal use only. May point to a temporary object.
658 * (Pay no attention to the man behind the curtain.)
659 *
660 * At most one of path.wide or path.narrow will be non-NULL.
661 * If path was None and path.nullable was set,
662 * or if path was an integer and path.allow_fd was set,
663 * both path.wide and path.narrow will be NULL
664 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200665 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700666 * path_converter takes care to not write to the path_t
667 * unless it's successful. However it must reset the
668 * "cleanup" field each time it's called.
669 *
670 * Use as follows:
671 * path_t path;
672 * memset(&path, 0, sizeof(path));
673 * PyArg_ParseTuple(args, "O&", path_converter, &path);
674 * // ... use values from path ...
675 * path_cleanup(&path);
676 *
677 * (Note that if PyArg_Parse fails you don't need to call
678 * path_cleanup(). However it is safe to do so.)
679 */
680typedef struct {
681 char *function_name;
682 char *argument_name;
683 int nullable;
684 int allow_fd;
685 wchar_t *wide;
686 char *narrow;
687 int fd;
688 Py_ssize_t length;
689 PyObject *object;
690 PyObject *cleanup;
691} path_t;
692
693static void
694path_cleanup(path_t *path) {
695 if (path->cleanup) {
696 Py_DECREF(path->cleanup);
697 path->cleanup = NULL;
698 }
699}
700
701static int
702path_converter(PyObject *o, void *p) {
703 path_t *path = (path_t *)p;
704 PyObject *unicode, *bytes;
705 Py_ssize_t length;
706 char *narrow;
707
708#define FORMAT_EXCEPTION(exc, fmt) \
709 PyErr_Format(exc, "%s%s" fmt, \
710 path->function_name ? path->function_name : "", \
711 path->function_name ? ": " : "", \
712 path->argument_name ? path->argument_name : "path")
713
714 /* Py_CLEANUP_SUPPORTED support */
715 if (o == NULL) {
716 path_cleanup(path);
717 return 1;
718 }
719
720 /* ensure it's always safe to call path_cleanup() */
721 path->cleanup = NULL;
722
723 if (o == Py_None) {
724 if (!path->nullable) {
725 FORMAT_EXCEPTION(PyExc_TypeError,
726 "can't specify None for %s argument");
727 return 0;
728 }
729 path->wide = NULL;
730 path->narrow = NULL;
731 path->length = 0;
732 path->object = o;
733 path->fd = -1;
734 return 1;
735 }
736
737 unicode = PyUnicode_FromObject(o);
738 if (unicode) {
739#ifdef MS_WINDOWS
740 wchar_t *wide;
741 length = PyUnicode_GET_SIZE(unicode);
742 if (length > 32767) {
743 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
744 Py_DECREF(unicode);
745 return 0;
746 }
747
748 wide = PyUnicode_AsUnicode(unicode);
749 if (!wide) {
750 Py_DECREF(unicode);
751 return 0;
752 }
753
754 path->wide = wide;
755 path->narrow = NULL;
756 path->length = length;
757 path->object = o;
758 path->fd = -1;
759 path->cleanup = unicode;
760 return Py_CLEANUP_SUPPORTED;
761#else
762 int converted = PyUnicode_FSConverter(unicode, &bytes);
763 Py_DECREF(unicode);
764 if (!converted)
765 bytes = NULL;
766#endif
767 }
768 else {
769 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200770 if (PyObject_CheckBuffer(o))
771 bytes = PyBytes_FromObject(o);
772 else
773 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700774 if (!bytes) {
775 PyErr_Clear();
776 if (path->allow_fd) {
777 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200778 int result = _fd_converter(o, &fd,
779 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700780 if (result) {
781 path->wide = NULL;
782 path->narrow = NULL;
783 path->length = 0;
784 path->object = o;
785 path->fd = fd;
786 return result;
787 }
788 }
789 }
790 }
791
792 if (!bytes) {
793 if (!PyErr_Occurred())
794 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
795 return 0;
796 }
797
798#ifdef MS_WINDOWS
799 if (win32_warn_bytes_api()) {
800 Py_DECREF(bytes);
801 return 0;
802 }
803#endif
804
805 length = PyBytes_GET_SIZE(bytes);
806#ifdef MS_WINDOWS
807 if (length > MAX_PATH) {
808 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
809 Py_DECREF(bytes);
810 return 0;
811 }
812#endif
813
814 narrow = PyBytes_AS_STRING(bytes);
815 if (length != strlen(narrow)) {
816 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s");
817 Py_DECREF(bytes);
818 return 0;
819 }
820
821 path->wide = NULL;
822 path->narrow = narrow;
823 path->length = length;
824 path->object = o;
825 path->fd = -1;
826 path->cleanup = bytes;
827 return Py_CLEANUP_SUPPORTED;
828}
829
830static void
831argument_unavailable_error(char *function_name, char *argument_name) {
832 PyErr_Format(PyExc_NotImplementedError,
833 "%s%s%s unavailable on this platform",
834 (function_name != NULL) ? function_name : "",
835 (function_name != NULL) ? ": ": "",
836 argument_name);
837}
838
839static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200840dir_fd_unavailable(PyObject *o, void *p)
841{
842 int dir_fd;
843 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700844 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200845 if (dir_fd != DEFAULT_DIR_FD) {
846 argument_unavailable_error(NULL, "dir_fd");
847 return 0;
848 }
849 *(int *)p = dir_fd;
850 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700851}
852
853static int
854fd_specified(char *function_name, int fd) {
855 if (fd == -1)
856 return 0;
857
858 argument_unavailable_error(function_name, "fd");
859 return 1;
860}
861
862static int
863follow_symlinks_specified(char *function_name, int follow_symlinks) {
864 if (follow_symlinks)
865 return 0;
866
867 argument_unavailable_error(function_name, "follow_symlinks");
868 return 1;
869}
870
871static int
872path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
873 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
874 PyErr_Format(PyExc_ValueError,
875 "%s: can't specify dir_fd without matching path",
876 function_name);
877 return 1;
878 }
879 return 0;
880}
881
882static int
883dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
884 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
885 PyErr_Format(PyExc_ValueError,
886 "%s: can't specify both dir_fd and fd",
887 function_name);
888 return 1;
889 }
890 return 0;
891}
892
893static int
894fd_and_follow_symlinks_invalid(char *function_name, int fd,
895 int follow_symlinks) {
896 if ((fd > 0) && (!follow_symlinks)) {
897 PyErr_Format(PyExc_ValueError,
898 "%s: cannot use fd and follow_symlinks together",
899 function_name);
900 return 1;
901 }
902 return 0;
903}
904
905static int
906dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
907 int follow_symlinks) {
908 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
909 PyErr_Format(PyExc_ValueError,
910 "%s: cannot use dir_fd and follow_symlinks together",
911 function_name);
912 return 1;
913 }
914 return 0;
915}
916
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200917/* A helper used by a number of POSIX-only functions */
918#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000919static int
920_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000921{
922#if !defined(HAVE_LARGEFILE_SUPPORT)
923 *((off_t*)addr) = PyLong_AsLong(arg);
924#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000925 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000926#endif
927 if (PyErr_Occurred())
928 return 0;
929 return 1;
930}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200931#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000932
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000933#if defined _MSC_VER && _MSC_VER >= 1400
934/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov737fb892012-12-18 21:14:22 +0200935 * valid and raise an assertion if it isn't.
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000936 * Normally, an invalid fd is likely to be a C program error and therefore
937 * an assertion can be useful, but it does contradict the POSIX standard
938 * which for write(2) states:
939 * "Otherwise, -1 shall be returned and errno set to indicate the error."
940 * "[EBADF] The fildes argument is not a valid file descriptor open for
941 * writing."
942 * Furthermore, python allows the user to enter any old integer
943 * as a fd and should merely raise a python exception on error.
944 * The Microsoft CRT doesn't provide an official way to check for the
945 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000946 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000947 * internal structures involved.
948 * The structures below must be updated for each version of visual studio
949 * according to the file internal.h in the CRT source, until MS comes
950 * up with a less hacky way to do this.
951 * (all of this is to avoid globally modifying the CRT behaviour using
952 * _set_invalid_parameter_handler() and _CrtSetReportMode())
953 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000954/* The actual size of the structure is determined at runtime.
955 * Only the first items must be present.
956 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000957typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000958 intptr_t osfhnd;
959 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000960} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000961
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000962extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000963#define IOINFO_L2E 5
964#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
965#define IOINFO_ARRAYS 64
966#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
967#define FOPEN 0x01
968#define _NO_CONSOLE_FILENO (intptr_t)-2
969
970/* This function emulates what the windows CRT does to validate file handles */
971int
972_PyVerify_fd(int fd)
973{
Victor Stinner8c62be82010-05-06 00:08:46 +0000974 const int i1 = fd >> IOINFO_L2E;
975 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000976
Antoine Pitrou22e41552010-08-15 18:07:50 +0000977 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000978
Victor Stinner8c62be82010-05-06 00:08:46 +0000979 /* Determine the actual size of the ioinfo structure,
980 * as used by the CRT loaded in memory
981 */
982 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
983 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
984 }
985 if (sizeof_ioinfo == 0) {
986 /* This should not happen... */
987 goto fail;
988 }
989
990 /* See that it isn't a special CLEAR fileno */
991 if (fd != _NO_CONSOLE_FILENO) {
992 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
993 * we check pointer validity and other info
994 */
995 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
996 /* finally, check that the file is open */
997 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
998 if (info->osfile & FOPEN) {
999 return 1;
1000 }
1001 }
1002 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +00001003 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +00001004 errno = EBADF;
1005 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001006}
1007
1008/* the special case of checking dup2. The target fd must be in a sensible range */
1009static int
1010_PyVerify_fd_dup2(int fd1, int fd2)
1011{
Victor Stinner8c62be82010-05-06 00:08:46 +00001012 if (!_PyVerify_fd(fd1))
1013 return 0;
1014 if (fd2 == _NO_CONSOLE_FILENO)
1015 return 0;
1016 if ((unsigned)fd2 < _NHANDLE_)
1017 return 1;
1018 else
1019 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001020}
1021#else
1022/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
1023#define _PyVerify_fd_dup2(A, B) (1)
1024#endif
1025
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001026#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001027/* The following structure was copied from
1028 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
1029 include doesn't seem to be present in the Windows SDK (at least as included
1030 with Visual Studio Express). */
1031typedef struct _REPARSE_DATA_BUFFER {
1032 ULONG ReparseTag;
1033 USHORT ReparseDataLength;
1034 USHORT Reserved;
1035 union {
1036 struct {
1037 USHORT SubstituteNameOffset;
1038 USHORT SubstituteNameLength;
1039 USHORT PrintNameOffset;
1040 USHORT PrintNameLength;
1041 ULONG Flags;
1042 WCHAR PathBuffer[1];
1043 } SymbolicLinkReparseBuffer;
1044
1045 struct {
1046 USHORT SubstituteNameOffset;
1047 USHORT SubstituteNameLength;
1048 USHORT PrintNameOffset;
1049 USHORT PrintNameLength;
1050 WCHAR PathBuffer[1];
1051 } MountPointReparseBuffer;
1052
1053 struct {
1054 UCHAR DataBuffer[1];
1055 } GenericReparseBuffer;
1056 };
1057} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
1058
1059#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
1060 GenericReparseBuffer)
1061#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
1062
1063static int
Brian Curtind25aef52011-06-13 15:16:04 -05001064win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001065{
1066 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1067 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1068 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001069
1070 if (0 == DeviceIoControl(
1071 reparse_point_handle,
1072 FSCTL_GET_REPARSE_POINT,
1073 NULL, 0, /* in buffer */
1074 target_buffer, sizeof(target_buffer),
1075 &n_bytes_returned,
1076 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001077 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001078
1079 if (reparse_tag)
1080 *reparse_tag = rdb->ReparseTag;
1081
Brian Curtind25aef52011-06-13 15:16:04 -05001082 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001083}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001084
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001085#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001086
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001087/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001088#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001089/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001090** environ directly, we must obtain it with _NSGetEnviron(). See also
1091** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001092*/
1093#include <crt_externs.h>
1094static char **environ;
1095#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001096extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001097#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001098
Barry Warsaw53699e91996-12-10 23:23:01 +00001099static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001100convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001101{
Victor Stinner8c62be82010-05-06 00:08:46 +00001102 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001103#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001104 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001105#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001106 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001107#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001108#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001109 APIRET rc;
1110 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
1111#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001112
Victor Stinner8c62be82010-05-06 00:08:46 +00001113 d = PyDict_New();
1114 if (d == NULL)
1115 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001116#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001117 if (environ == NULL)
1118 environ = *_NSGetEnviron();
1119#endif
1120#ifdef MS_WINDOWS
1121 /* _wenviron must be initialized in this way if the program is started
1122 through main() instead of wmain(). */
1123 _wgetenv(L"");
1124 if (_wenviron == NULL)
1125 return d;
1126 /* This part ignores errors */
1127 for (e = _wenviron; *e != NULL; e++) {
1128 PyObject *k;
1129 PyObject *v;
1130 wchar_t *p = wcschr(*e, L'=');
1131 if (p == NULL)
1132 continue;
1133 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1134 if (k == NULL) {
1135 PyErr_Clear();
1136 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001137 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001138 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1139 if (v == NULL) {
1140 PyErr_Clear();
1141 Py_DECREF(k);
1142 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001143 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001144 if (PyDict_GetItem(d, k) == NULL) {
1145 if (PyDict_SetItem(d, k, v) != 0)
1146 PyErr_Clear();
1147 }
1148 Py_DECREF(k);
1149 Py_DECREF(v);
1150 }
1151#else
1152 if (environ == NULL)
1153 return d;
1154 /* This part ignores errors */
1155 for (e = environ; *e != NULL; e++) {
1156 PyObject *k;
1157 PyObject *v;
1158 char *p = strchr(*e, '=');
1159 if (p == NULL)
1160 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001161 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001162 if (k == NULL) {
1163 PyErr_Clear();
1164 continue;
1165 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001166 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001167 if (v == NULL) {
1168 PyErr_Clear();
1169 Py_DECREF(k);
1170 continue;
1171 }
1172 if (PyDict_GetItem(d, k) == NULL) {
1173 if (PyDict_SetItem(d, k, v) != 0)
1174 PyErr_Clear();
1175 }
1176 Py_DECREF(k);
1177 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001178 }
1179#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001180#if defined(PYOS_OS2)
1181 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
1182 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
1183 PyObject *v = PyBytes_FromString(buffer);
1184 PyDict_SetItemString(d, "BEGINLIBPATH", v);
1185 Py_DECREF(v);
1186 }
1187 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
1188 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
1189 PyObject *v = PyBytes_FromString(buffer);
1190 PyDict_SetItemString(d, "ENDLIBPATH", v);
1191 Py_DECREF(v);
1192 }
1193#endif
1194 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195}
1196
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001197/* Set a POSIX-specific error from errno, and return NULL */
1198
Barry Warsawd58d7641998-07-23 16:14:40 +00001199static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001200posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001201{
Victor Stinner8c62be82010-05-06 00:08:46 +00001202 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001203}
Barry Warsawd58d7641998-07-23 16:14:40 +00001204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001205posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +00001206{
Victor Stinner8c62be82010-05-06 00:08:46 +00001207 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +00001208}
1209
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001210
Mark Hammondef8b6542001-05-13 08:04:26 +00001211static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +00001212posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +00001213{
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001214 PyObject *name_str, *rc;
1215 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
1216 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +00001217 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +00001218 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
1219 name_str);
1220 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +00001221 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +00001222}
1223
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001224#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001225static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001226win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001227{
Victor Stinner8c62be82010-05-06 00:08:46 +00001228 /* XXX We should pass the function name along in the future.
1229 (winreg.c also wants to pass the function name.)
1230 This would however require an additional param to the
1231 Windows error object, which is non-trivial.
1232 */
1233 errno = GetLastError();
1234 if (filename)
1235 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1236 else
1237 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001238}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001239
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001240static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001241win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001242{
Victor Stinner8c62be82010-05-06 00:08:46 +00001243 /* XXX - see win32_error for comments on 'function' */
1244 errno = GetLastError();
1245 if (filename)
1246 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
1247 else
1248 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001249}
1250
Victor Stinnereb5657a2011-09-30 01:44:27 +02001251static PyObject *
1252win32_error_object(char* function, PyObject* filename)
1253{
1254 /* XXX - see win32_error for comments on 'function' */
1255 errno = GetLastError();
1256 if (filename)
1257 return PyErr_SetExcFromWindowsErrWithFilenameObject(
1258 PyExc_WindowsError,
1259 errno,
1260 filename);
1261 else
1262 return PyErr_SetFromWindowsErr(errno);
1263}
1264
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001265#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001266
Larry Hastings9cf065c2012-06-22 16:30:09 -07001267/*
1268 * Some functions return Win32 errors, others only ever use posix_error
1269 * (this is for backwards compatibility with exceptions)
1270 */
1271static PyObject *
1272path_posix_error(char *function_name, path_t *path)
1273{
1274 if (path->narrow)
1275 return posix_error_with_filename(path->narrow);
1276 return posix_error();
1277}
1278
1279static PyObject *
1280path_error(char *function_name, path_t *path)
1281{
1282#ifdef MS_WINDOWS
1283 if (path->narrow)
1284 return win32_error(function_name, path->narrow);
1285 if (path->wide)
1286 return win32_error_unicode(function_name, path->wide);
1287 return win32_error(function_name, NULL);
1288#else
1289 return path_posix_error(function_name, path);
1290#endif
1291}
1292
Guido van Rossumd48f2521997-12-05 22:19:34 +00001293#if defined(PYOS_OS2)
1294/**********************************************************************
1295 * Helper Function to Trim and Format OS/2 Messages
1296 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001297static void
Guido van Rossumd48f2521997-12-05 22:19:34 +00001298os2_formatmsg(char *msgbuf, int msglen, char *reason)
1299{
1300 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
1301
1302 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
1303 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
1304
Antoine Pitrou4de74572013-02-09 23:11:27 +01001305 while (lastc > msgbuf && Py_ISSPACE(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +00001306 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
1307 }
1308
1309 /* Add Optional Reason Text */
1310 if (reason) {
1311 strcat(msgbuf, " : ");
1312 strcat(msgbuf, reason);
1313 }
1314}
1315
1316/**********************************************************************
1317 * Decode an OS/2 Operating System Error Code
1318 *
1319 * A convenience function to lookup an OS/2 error code and return a
1320 * text message we can use to raise a Python exception.
1321 *
1322 * Notes:
1323 * The messages for errors returned from the OS/2 kernel reside in
1324 * the file OSO001.MSG in the \OS2 directory hierarchy.
1325 *
1326 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +00001327static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +00001328os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
1329{
1330 APIRET rc;
1331 ULONG msglen;
1332
1333 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
1334 Py_BEGIN_ALLOW_THREADS
1335 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
1336 errorcode, "oso001.msg", &msglen);
1337 Py_END_ALLOW_THREADS
1338
1339 if (rc == NO_ERROR)
1340 os2_formatmsg(msgbuf, msglen, reason);
1341 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +00001342 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +00001343 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001344
1345 return msgbuf;
1346}
1347
1348/* Set an OS/2-specific error and return NULL. OS/2 kernel
1349 errors are not in a global variable e.g. 'errno' nor are
1350 they congruent with posix error numbers. */
1351
Victor Stinner8c62be82010-05-06 00:08:46 +00001352static PyObject *
1353os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001354{
1355 char text[1024];
1356 PyObject *v;
1357
1358 os2_strerror(text, sizeof(text), code, "");
1359
1360 v = Py_BuildValue("(is)", code, text);
1361 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +00001362 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001363 Py_DECREF(v);
1364 }
1365 return NULL; /* Signal to Python that an Exception is Pending */
1366}
1367
1368#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369
1370/* POSIX generic methods */
1371
Barry Warsaw53699e91996-12-10 23:23:01 +00001372static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001373posix_fildes(PyObject *fdobj, int (*func)(int))
1374{
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 int fd;
1376 int res;
1377 fd = PyObject_AsFileDescriptor(fdobj);
1378 if (fd < 0)
1379 return NULL;
1380 if (!_PyVerify_fd(fd))
1381 return posix_error();
1382 Py_BEGIN_ALLOW_THREADS
1383 res = (*func)(fd);
1384 Py_END_ALLOW_THREADS
1385 if (res < 0)
1386 return posix_error();
1387 Py_INCREF(Py_None);
1388 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001389}
Guido van Rossum21142a01999-01-08 21:05:37 +00001390
1391static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393{
Victor Stinner8c62be82010-05-06 00:08:46 +00001394 PyObject *opath1 = NULL;
1395 char *path1;
1396 int res;
1397 if (!PyArg_ParseTuple(args, format,
1398 PyUnicode_FSConverter, &opath1))
1399 return NULL;
1400 path1 = PyBytes_AsString(opath1);
1401 Py_BEGIN_ALLOW_THREADS
1402 res = (*func)(path1);
1403 Py_END_ALLOW_THREADS
1404 if (res < 0)
1405 return posix_error_with_allocated_filename(opath1);
1406 Py_DECREF(opath1);
1407 Py_INCREF(Py_None);
1408 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001409}
1410
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001411
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001412#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001413static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +00001414win32_1str(PyObject* args, char* func,
1415 char* format, BOOL (__stdcall *funcA)(LPCSTR),
1416 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417{
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001419 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001421
Victor Stinnereb5657a2011-09-30 01:44:27 +02001422 if (PyArg_ParseTuple(args, wformat, &uni))
1423 {
1424 wchar_t *wstr = PyUnicode_AsUnicode(uni);
1425 if (wstr == NULL)
1426 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001427 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001428 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 Py_END_ALLOW_THREADS
1430 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001431 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 Py_INCREF(Py_None);
1433 return Py_None;
1434 }
Victor Stinnereb5657a2011-09-30 01:44:27 +02001435 PyErr_Clear();
1436
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 if (!PyArg_ParseTuple(args, format, &ansi))
1438 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001439 if (win32_warn_bytes_api())
1440 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001441 Py_BEGIN_ALLOW_THREADS
1442 result = funcA(ansi);
1443 Py_END_ALLOW_THREADS
1444 if (!result)
1445 return win32_error(func, ansi);
1446 Py_INCREF(Py_None);
1447 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001448
1449}
1450
1451/* This is a reimplementation of the C library's chdir function,
1452 but one that produces Win32 errors instead of DOS error codes.
1453 chdir is essentially a wrapper around SetCurrentDirectory; however,
1454 it also needs to set "magic" environment variables indicating
1455 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001456static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001457win32_chdir(LPCSTR path)
1458{
Victor Stinner8c62be82010-05-06 00:08:46 +00001459 char new_path[MAX_PATH+1];
1460 int result;
1461 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001462
Victor Stinner8c62be82010-05-06 00:08:46 +00001463 if(!SetCurrentDirectoryA(path))
1464 return FALSE;
1465 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
1466 if (!result)
1467 return FALSE;
1468 /* In the ANSI API, there should not be any paths longer
1469 than MAX_PATH. */
1470 assert(result <= MAX_PATH+1);
1471 if (strncmp(new_path, "\\\\", 2) == 0 ||
1472 strncmp(new_path, "//", 2) == 0)
1473 /* UNC path, nothing to do. */
1474 return TRUE;
1475 env[1] = new_path[0];
1476 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001477}
1478
1479/* The Unicode version differs from the ANSI version
1480 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001481static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001482win32_wchdir(LPCWSTR path)
1483{
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
1485 int result;
1486 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001487
Victor Stinner8c62be82010-05-06 00:08:46 +00001488 if(!SetCurrentDirectoryW(path))
1489 return FALSE;
1490 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
1491 if (!result)
1492 return FALSE;
1493 if (result > MAX_PATH+1) {
1494 new_path = malloc(result * sizeof(wchar_t));
1495 if (!new_path) {
1496 SetLastError(ERROR_OUTOFMEMORY);
1497 return FALSE;
1498 }
1499 result = GetCurrentDirectoryW(result, new_path);
1500 if (!result) {
1501 free(new_path);
1502 return FALSE;
1503 }
1504 }
1505 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1506 wcsncmp(new_path, L"//", 2) == 0)
1507 /* UNC path, nothing to do. */
1508 return TRUE;
1509 env[1] = new_path[0];
1510 result = SetEnvironmentVariableW(env, new_path);
1511 if (new_path != _new_path)
1512 free(new_path);
1513 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001514}
1515#endif
1516
Martin v. Löwis14694662006-02-03 12:54:16 +00001517#ifdef MS_WINDOWS
1518/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1519 - time stamps are restricted to second resolution
1520 - file modification times suffer from forth-and-back conversions between
1521 UTC and local time
1522 Therefore, we implement our own stat, based on the Win32 API directly.
1523*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001524#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001525
1526struct win32_stat{
1527 int st_dev;
1528 __int64 st_ino;
1529 unsigned short st_mode;
1530 int st_nlink;
1531 int st_uid;
1532 int st_gid;
1533 int st_rdev;
1534 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001535 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001536 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001537 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001538 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001539 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001540 int st_ctime_nsec;
1541};
1542
1543static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1544
1545static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001546FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001547{
Victor Stinner8c62be82010-05-06 00:08:46 +00001548 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1549 /* Cannot simply cast and dereference in_ptr,
1550 since it might not be aligned properly */
1551 __int64 in;
1552 memcpy(&in, in_ptr, sizeof(in));
1553 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001554 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001555}
1556
Thomas Wouters477c8d52006-05-27 19:21:47 +00001557static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001558time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001559{
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 /* XXX endianness */
1561 __int64 out;
1562 out = time_in + secs_between_epochs;
1563 out = out * 10000000 + nsec_in / 100;
1564 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565}
1566
Martin v. Löwis14694662006-02-03 12:54:16 +00001567/* Below, we *know* that ugo+r is 0444 */
1568#if _S_IREAD != 0400
1569#error Unsupported C library
1570#endif
1571static int
1572attributes_to_mode(DWORD attr)
1573{
Victor Stinner8c62be82010-05-06 00:08:46 +00001574 int m = 0;
1575 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1576 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1577 else
1578 m |= _S_IFREG;
1579 if (attr & FILE_ATTRIBUTE_READONLY)
1580 m |= 0444;
1581 else
1582 m |= 0666;
1583 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001584}
1585
1586static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001587attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001588{
Victor Stinner8c62be82010-05-06 00:08:46 +00001589 memset(result, 0, sizeof(*result));
1590 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1591 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1592 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1593 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1594 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001596 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001597 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1598 /* first clear the S_IFMT bits */
1599 result->st_mode ^= (result->st_mode & 0170000);
1600 /* now set the bits that make this a symlink */
1601 result->st_mode |= 0120000;
1602 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001603
Victor Stinner8c62be82010-05-06 00:08:46 +00001604 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001605}
1606
Guido van Rossumd8faa362007-04-27 19:54:29 +00001607static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001608attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001609{
Victor Stinner8c62be82010-05-06 00:08:46 +00001610 HANDLE hFindFile;
1611 WIN32_FIND_DATAA FileData;
1612 hFindFile = FindFirstFileA(pszFile, &FileData);
1613 if (hFindFile == INVALID_HANDLE_VALUE)
1614 return FALSE;
1615 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001616 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001617 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001618 info->dwFileAttributes = FileData.dwFileAttributes;
1619 info->ftCreationTime = FileData.ftCreationTime;
1620 info->ftLastAccessTime = FileData.ftLastAccessTime;
1621 info->ftLastWriteTime = FileData.ftLastWriteTime;
1622 info->nFileSizeHigh = FileData.nFileSizeHigh;
1623 info->nFileSizeLow = FileData.nFileSizeLow;
1624/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001625 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1626 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001627 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001628}
1629
1630static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001631attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001632{
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 HANDLE hFindFile;
1634 WIN32_FIND_DATAW FileData;
1635 hFindFile = FindFirstFileW(pszFile, &FileData);
1636 if (hFindFile == INVALID_HANDLE_VALUE)
1637 return FALSE;
1638 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001641 info->dwFileAttributes = FileData.dwFileAttributes;
1642 info->ftCreationTime = FileData.ftCreationTime;
1643 info->ftLastAccessTime = FileData.ftLastAccessTime;
1644 info->ftLastWriteTime = FileData.ftLastWriteTime;
1645 info->nFileSizeHigh = FileData.nFileSizeHigh;
1646 info->nFileSizeLow = FileData.nFileSizeLow;
1647/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001648 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1649 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001651}
1652
Brian Curtind25aef52011-06-13 15:16:04 -05001653/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1654static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001655static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1656 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001657static int
Brian Curtind25aef52011-06-13 15:16:04 -05001658check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001659{
Brian Curtind25aef52011-06-13 15:16:04 -05001660 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001661 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1662 DWORD);
1663
Brian Curtind25aef52011-06-13 15:16:04 -05001664 /* only recheck */
1665 if (!has_GetFinalPathNameByHandle)
1666 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001667 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001668 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1669 "GetFinalPathNameByHandleA");
1670 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1671 "GetFinalPathNameByHandleW");
1672 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1673 Py_GetFinalPathNameByHandleW;
1674 }
1675 return has_GetFinalPathNameByHandle;
1676}
1677
1678static BOOL
1679get_target_path(HANDLE hdl, wchar_t **target_path)
1680{
1681 int buf_size, result_length;
1682 wchar_t *buf;
1683
1684 /* We have a good handle to the target, use it to determine
1685 the target path name (then we'll call lstat on it). */
1686 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1687 VOLUME_NAME_DOS);
1688 if(!buf_size)
1689 return FALSE;
1690
1691 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001692 if (!buf) {
1693 SetLastError(ERROR_OUTOFMEMORY);
1694 return FALSE;
1695 }
1696
Brian Curtind25aef52011-06-13 15:16:04 -05001697 result_length = Py_GetFinalPathNameByHandleW(hdl,
1698 buf, buf_size, VOLUME_NAME_DOS);
1699
1700 if(!result_length) {
1701 free(buf);
1702 return FALSE;
1703 }
1704
1705 if(!CloseHandle(hdl)) {
1706 free(buf);
1707 return FALSE;
1708 }
1709
1710 buf[result_length] = 0;
1711
1712 *target_path = buf;
1713 return TRUE;
1714}
1715
1716static int
1717win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1718 BOOL traverse);
1719static int
1720win32_xstat_impl(const char *path, struct win32_stat *result,
1721 BOOL traverse)
1722{
Victor Stinner26de69d2011-06-17 15:15:38 +02001723 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001724 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001725 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001727 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001728 const char *dot;
1729
Brian Curtind25aef52011-06-13 15:16:04 -05001730 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001731 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1732 traverse reparse point. */
1733 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001734 }
1735
Brian Curtinf5e76d02010-11-24 13:14:05 +00001736 hFile = CreateFileA(
1737 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001738 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001739 0, /* share mode */
1740 NULL, /* security attributes */
1741 OPEN_EXISTING,
1742 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001743 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1744 Because of this, calls like GetFinalPathNameByHandle will return
1745 the symlink path agin and not the actual final path. */
1746 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1747 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001748 NULL);
1749
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001750 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001751 /* Either the target doesn't exist, or we don't have access to
1752 get a handle to it. If the former, we need to return an error.
1753 If the latter, we can use attributes_from_dir. */
1754 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001755 return -1;
1756 /* Could not get attributes on open file. Fall back to
1757 reading the directory. */
1758 if (!attributes_from_dir(path, &info, &reparse_tag))
1759 /* Very strange. This should not fail now */
1760 return -1;
1761 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1762 if (traverse) {
1763 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001764 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001765 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001766 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001767 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001768 } else {
1769 if (!GetFileInformationByHandle(hFile, &info)) {
1770 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001771 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001772 }
1773 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001774 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1775 return -1;
1776
1777 /* Close the outer open file handle now that we're about to
1778 reopen it with different flags. */
1779 if (!CloseHandle(hFile))
1780 return -1;
1781
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001782 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001783 /* In order to call GetFinalPathNameByHandle we need to open
1784 the file without the reparse handling flag set. */
1785 hFile2 = CreateFileA(
1786 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1787 NULL, OPEN_EXISTING,
1788 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1789 NULL);
1790 if (hFile2 == INVALID_HANDLE_VALUE)
1791 return -1;
1792
1793 if (!get_target_path(hFile2, &target_path))
1794 return -1;
1795
1796 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001797 free(target_path);
1798 return code;
1799 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001800 } else
1801 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001802 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001803 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001804
1805 /* Set S_IEXEC if it is an .exe, .bat, ... */
1806 dot = strrchr(path, '.');
1807 if (dot) {
1808 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1809 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1810 result->st_mode |= 0111;
1811 }
1812 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001813}
1814
1815static int
Brian Curtind25aef52011-06-13 15:16:04 -05001816win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1817 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001818{
1819 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001820 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001821 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001822 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001823 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001824 const wchar_t *dot;
1825
Brian Curtind25aef52011-06-13 15:16:04 -05001826 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001827 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1828 traverse reparse point. */
1829 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001830 }
1831
Brian Curtinf5e76d02010-11-24 13:14:05 +00001832 hFile = CreateFileW(
1833 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001834 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001835 0, /* share mode */
1836 NULL, /* security attributes */
1837 OPEN_EXISTING,
1838 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001839 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1840 Because of this, calls like GetFinalPathNameByHandle will return
1841 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001842 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001843 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001844 NULL);
1845
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001846 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001847 /* Either the target doesn't exist, or we don't have access to
1848 get a handle to it. If the former, we need to return an error.
1849 If the latter, we can use attributes_from_dir. */
1850 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001851 return -1;
1852 /* Could not get attributes on open file. Fall back to
1853 reading the directory. */
1854 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1855 /* Very strange. This should not fail now */
1856 return -1;
1857 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1858 if (traverse) {
1859 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001860 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001861 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001862 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001863 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001864 } else {
1865 if (!GetFileInformationByHandle(hFile, &info)) {
1866 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001867 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001868 }
1869 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001870 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1871 return -1;
1872
1873 /* Close the outer open file handle now that we're about to
1874 reopen it with different flags. */
1875 if (!CloseHandle(hFile))
1876 return -1;
1877
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001878 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001879 /* In order to call GetFinalPathNameByHandle we need to open
1880 the file without the reparse handling flag set. */
1881 hFile2 = CreateFileW(
1882 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1883 NULL, OPEN_EXISTING,
1884 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1885 NULL);
1886 if (hFile2 == INVALID_HANDLE_VALUE)
1887 return -1;
1888
1889 if (!get_target_path(hFile2, &target_path))
1890 return -1;
1891
1892 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001893 free(target_path);
1894 return code;
1895 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001896 } else
1897 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001898 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001899 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001900
1901 /* Set S_IEXEC if it is an .exe, .bat, ... */
1902 dot = wcsrchr(path, '.');
1903 if (dot) {
1904 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1905 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1906 result->st_mode |= 0111;
1907 }
1908 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001909}
1910
1911static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001912win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001913{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001914 /* Protocol violation: we explicitly clear errno, instead of
1915 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001916 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001917 errno = 0;
1918 return code;
1919}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001920
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001921static int
1922win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1923{
1924 /* Protocol violation: we explicitly clear errno, instead of
1925 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001926 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001927 errno = 0;
1928 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001929}
Brian Curtind25aef52011-06-13 15:16:04 -05001930/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001931
1932 In Posix, stat automatically traverses symlinks and returns the stat
1933 structure for the target. In Windows, the equivalent GetFileAttributes by
1934 default does not traverse symlinks and instead returns attributes for
1935 the symlink.
1936
1937 Therefore, win32_lstat will get the attributes traditionally, and
1938 win32_stat will first explicitly resolve the symlink target and then will
1939 call win32_lstat on that result.
1940
Ezio Melotti4969f702011-03-15 05:59:46 +02001941 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001942
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001943static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001944win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001945{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001946 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001947}
1948
Victor Stinner8c62be82010-05-06 00:08:46 +00001949static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001950win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001951{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001952 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001953}
1954
1955static int
1956win32_stat(const char* path, struct win32_stat *result)
1957{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001958 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001959}
1960
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001961static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001962win32_stat_w(const wchar_t* path, struct win32_stat *result)
1963{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001964 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001965}
1966
1967static int
1968win32_fstat(int file_number, struct win32_stat *result)
1969{
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 BY_HANDLE_FILE_INFORMATION info;
1971 HANDLE h;
1972 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001973
Richard Oudkerk2240ac12012-07-06 12:05:32 +01001974 if (!_PyVerify_fd(file_number))
1975 h = INVALID_HANDLE_VALUE;
1976 else
1977 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001978
Victor Stinner8c62be82010-05-06 00:08:46 +00001979 /* Protocol violation: we explicitly clear errno, instead of
1980 setting it to a POSIX error. Callers should use GetLastError. */
1981 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001982
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 if (h == INVALID_HANDLE_VALUE) {
1984 /* This is really a C library error (invalid file handle).
1985 We set the Win32 error to the closes one matching. */
1986 SetLastError(ERROR_INVALID_HANDLE);
1987 return -1;
1988 }
1989 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001990
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 type = GetFileType(h);
1992 if (type == FILE_TYPE_UNKNOWN) {
1993 DWORD error = GetLastError();
1994 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001995 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 }
1997 /* else: valid but unknown file */
1998 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001999
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 if (type != FILE_TYPE_DISK) {
2001 if (type == FILE_TYPE_CHAR)
2002 result->st_mode = _S_IFCHR;
2003 else if (type == FILE_TYPE_PIPE)
2004 result->st_mode = _S_IFIFO;
2005 return 0;
2006 }
2007
2008 if (!GetFileInformationByHandle(h, &info)) {
2009 return -1;
2010 }
2011
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00002012 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
2015 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00002016}
2017
2018#endif /* MS_WINDOWS */
2019
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002020PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002021"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002022This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002023 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002024or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
2025\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002026Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
2027or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002028\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002029See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002030
2031static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 {"st_mode", "protection bits"},
2033 {"st_ino", "inode"},
2034 {"st_dev", "device"},
2035 {"st_nlink", "number of hard links"},
2036 {"st_uid", "user ID of owner"},
2037 {"st_gid", "group ID of owner"},
2038 {"st_size", "total size, in bytes"},
2039 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
2040 {NULL, "integer time of last access"},
2041 {NULL, "integer time of last modification"},
2042 {NULL, "integer time of last change"},
2043 {"st_atime", "time of last access"},
2044 {"st_mtime", "time of last modification"},
2045 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07002046 {"st_atime_ns", "time of last access in nanoseconds"},
2047 {"st_mtime_ns", "time of last modification in nanoseconds"},
2048 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002049#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002051#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002052#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002053 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002054#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002055#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002057#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002058#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002059 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002060#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002061#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002063#endif
2064#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002066#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002068};
2069
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002070#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07002071#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002072#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07002073#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002074#endif
2075
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002076#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002077#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
2078#else
2079#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
2080#endif
2081
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002082#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002083#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
2084#else
2085#define ST_RDEV_IDX ST_BLOCKS_IDX
2086#endif
2087
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002088#ifdef HAVE_STRUCT_STAT_ST_FLAGS
2089#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
2090#else
2091#define ST_FLAGS_IDX ST_RDEV_IDX
2092#endif
2093
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002094#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002095#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002096#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00002097#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002098#endif
2099
2100#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
2101#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
2102#else
2103#define ST_BIRTHTIME_IDX ST_GEN_IDX
2104#endif
2105
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002106static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 "stat_result", /* name */
2108 stat_result__doc__, /* doc */
2109 stat_result_fields,
2110 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002111};
2112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002113PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002114"statvfs_result: Result from statvfs or fstatvfs.\n\n\
2115This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002116 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00002117or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002118\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002119See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002120
2121static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002122 {"f_bsize", },
2123 {"f_frsize", },
2124 {"f_blocks", },
2125 {"f_bfree", },
2126 {"f_bavail", },
2127 {"f_files", },
2128 {"f_ffree", },
2129 {"f_favail", },
2130 {"f_flag", },
2131 {"f_namemax",},
2132 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002133};
2134
2135static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 "statvfs_result", /* name */
2137 statvfs_result__doc__, /* doc */
2138 statvfs_result_fields,
2139 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002140};
2141
Ross Lagerwall7807c352011-03-17 20:20:30 +02002142#if defined(HAVE_WAITID) && !defined(__APPLE__)
2143PyDoc_STRVAR(waitid_result__doc__,
2144"waitid_result: Result from waitid.\n\n\
2145This object may be accessed either as a tuple of\n\
2146 (si_pid, si_uid, si_signo, si_status, si_code),\n\
2147or via the attributes si_pid, si_uid, and so on.\n\
2148\n\
2149See os.waitid for more information.");
2150
2151static PyStructSequence_Field waitid_result_fields[] = {
2152 {"si_pid", },
2153 {"si_uid", },
2154 {"si_signo", },
2155 {"si_status", },
2156 {"si_code", },
2157 {0}
2158};
2159
2160static PyStructSequence_Desc waitid_result_desc = {
2161 "waitid_result", /* name */
2162 waitid_result__doc__, /* doc */
2163 waitid_result_fields,
2164 5
2165};
2166static PyTypeObject WaitidResultType;
2167#endif
2168
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002169static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002170static PyTypeObject StatResultType;
2171static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002172#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05002173static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05002174#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002175static newfunc structseq_new;
2176
2177static PyObject *
2178statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2179{
Victor Stinner8c62be82010-05-06 00:08:46 +00002180 PyStructSequence *result;
2181 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002182
Victor Stinner8c62be82010-05-06 00:08:46 +00002183 result = (PyStructSequence*)structseq_new(type, args, kwds);
2184 if (!result)
2185 return NULL;
2186 /* If we have been initialized from a tuple,
2187 st_?time might be set to None. Initialize it
2188 from the int slots. */
2189 for (i = 7; i <= 9; i++) {
2190 if (result->ob_item[i+3] == Py_None) {
2191 Py_DECREF(Py_None);
2192 Py_INCREF(result->ob_item[i]);
2193 result->ob_item[i+3] = result->ob_item[i];
2194 }
2195 }
2196 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002197}
2198
2199
2200
2201/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00002202static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002203
2204PyDoc_STRVAR(stat_float_times__doc__,
2205"stat_float_times([newval]) -> oldval\n\n\
2206Determine whether os.[lf]stat represents time stamps as float objects.\n\
2207If newval is True, future calls to stat() return floats, if it is False,\n\
2208future calls return ints. \n\
2209If newval is omitted, return the current setting.\n");
2210
2211static PyObject*
2212stat_float_times(PyObject* self, PyObject *args)
2213{
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 int newval = -1;
2215 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2216 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002217 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2218 "stat_float_times() is deprecated",
2219 1))
2220 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002221 if (newval == -1)
2222 /* Return old value */
2223 return PyBool_FromLong(_stat_float_times);
2224 _stat_float_times = newval;
2225 Py_INCREF(Py_None);
2226 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002227}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002228
Larry Hastings6fe20b32012-04-19 15:07:49 -07002229static PyObject *billion = NULL;
2230
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002231static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002232fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002233{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002234 PyObject *s = _PyLong_FromTime_t(sec);
2235 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2236 PyObject *s_in_ns = NULL;
2237 PyObject *ns_total = NULL;
2238 PyObject *float_s = NULL;
2239
2240 if (!(s && ns_fractional))
2241 goto exit;
2242
2243 s_in_ns = PyNumber_Multiply(s, billion);
2244 if (!s_in_ns)
2245 goto exit;
2246
2247 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2248 if (!ns_total)
2249 goto exit;
2250
Victor Stinner4195b5c2012-02-08 23:03:19 +01002251 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002252 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2253 if (!float_s)
2254 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002255 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002256 else {
2257 float_s = s;
2258 Py_INCREF(float_s);
2259 }
2260
2261 PyStructSequence_SET_ITEM(v, index, s);
2262 PyStructSequence_SET_ITEM(v, index+3, float_s);
2263 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2264 s = NULL;
2265 float_s = NULL;
2266 ns_total = NULL;
2267exit:
2268 Py_XDECREF(s);
2269 Py_XDECREF(ns_fractional);
2270 Py_XDECREF(s_in_ns);
2271 Py_XDECREF(ns_total);
2272 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002273}
2274
Tim Peters5aa91602002-01-30 05:46:57 +00002275/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002276 (used by posix_stat() and posix_fstat()) */
2277static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002278_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002279{
Victor Stinner8c62be82010-05-06 00:08:46 +00002280 unsigned long ansec, mnsec, cnsec;
2281 PyObject *v = PyStructSequence_New(&StatResultType);
2282 if (v == NULL)
2283 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002284
Victor Stinner8c62be82010-05-06 00:08:46 +00002285 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002286#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 PyStructSequence_SET_ITEM(v, 1,
2288 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002289#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002290 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002291#endif
2292#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 PyStructSequence_SET_ITEM(v, 2,
2294 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002295#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002296 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002297#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002299#if defined(MS_WINDOWS)
2300 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2301 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2302#else
2303 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2304 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2305#endif
Fred Drake699f3522000-06-29 21:12:41 +00002306#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002307 PyStructSequence_SET_ITEM(v, 6,
2308 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002309#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002310 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002311#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002312
Martin v. Löwis14694662006-02-03 12:54:16 +00002313#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002314 ansec = st->st_atim.tv_nsec;
2315 mnsec = st->st_mtim.tv_nsec;
2316 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002317#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002318 ansec = st->st_atimespec.tv_nsec;
2319 mnsec = st->st_mtimespec.tv_nsec;
2320 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002321#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002322 ansec = st->st_atime_nsec;
2323 mnsec = st->st_mtime_nsec;
2324 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002325#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002326 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002327#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002328 fill_time(v, 7, st->st_atime, ansec);
2329 fill_time(v, 8, st->st_mtime, mnsec);
2330 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002331
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002332#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002333 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2334 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002335#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002336#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002337 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2338 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002339#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002340#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002341 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2342 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002343#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002344#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002345 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2346 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002347#endif
2348#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002349 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002350 PyObject *val;
2351 unsigned long bsec,bnsec;
2352 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002353#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002354 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002355#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002356 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002357#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002358 if (_stat_float_times) {
2359 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2360 } else {
2361 val = PyLong_FromLong((long)bsec);
2362 }
2363 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2364 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002365 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002366#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002367#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002368 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2369 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002370#endif
Fred Drake699f3522000-06-29 21:12:41 +00002371
Victor Stinner8c62be82010-05-06 00:08:46 +00002372 if (PyErr_Occurred()) {
2373 Py_DECREF(v);
2374 return NULL;
2375 }
Fred Drake699f3522000-06-29 21:12:41 +00002376
Victor Stinner8c62be82010-05-06 00:08:46 +00002377 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002378}
2379
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002380/* POSIX methods */
2381
Guido van Rossum94f6f721999-01-06 18:42:14 +00002382
2383static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002384posix_do_stat(char *function_name, path_t *path,
2385 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002386{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002387 STRUCT_STAT st;
2388 int result;
2389
2390#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2391 if (follow_symlinks_specified(function_name, follow_symlinks))
2392 return NULL;
2393#endif
2394
2395 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2396 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2397 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2398 return NULL;
2399
2400 Py_BEGIN_ALLOW_THREADS
2401 if (path->fd != -1)
2402 result = FSTAT(path->fd, &st);
2403 else
2404#ifdef MS_WINDOWS
2405 if (path->wide) {
2406 if (follow_symlinks)
2407 result = win32_stat_w(path->wide, &st);
2408 else
2409 result = win32_lstat_w(path->wide, &st);
2410 }
2411 else
2412#endif
2413#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2414 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2415 result = LSTAT(path->narrow, &st);
2416 else
2417#endif
2418#ifdef HAVE_FSTATAT
2419 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2420 result = fstatat(dir_fd, path->narrow, &st,
2421 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2422 else
2423#endif
2424 result = STAT(path->narrow, &st);
2425 Py_END_ALLOW_THREADS
2426
2427 if (result != 0)
2428 return path_error("stat", path);
2429
2430 return _pystat_fromstructstat(&st);
2431}
2432
2433PyDoc_STRVAR(posix_stat__doc__,
2434"stat(path, *, dir_fd=None, follow_symlinks=True) -> stat result\n\n\
2435Perform a stat system call on the given path.\n\
2436\n\
2437path may be specified as either a string or as an open file descriptor.\n\
2438\n\
2439If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2440 and path should be relative; path will then be relative to that directory.\n\
2441 dir_fd may not be supported on your platform; if it is unavailable, using\n\
2442 it will raise a NotImplementedError.\n\
2443If follow_symlinks is False, and the last element of the path is a symbolic\n\
2444 link, stat will examine the symbolic link itself instead of the file the\n\
2445 link points to.\n\
2446It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2447 an open file descriptor.");
2448
2449static PyObject *
2450posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
2451{
2452 static char *keywords[] = {"path", "dir_fd", "follow_symlinks", NULL};
2453 path_t path;
2454 int dir_fd = DEFAULT_DIR_FD;
2455 int follow_symlinks = 1;
2456 PyObject *return_value;
2457
2458 memset(&path, 0, sizeof(path));
2459 path.allow_fd = 1;
2460 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
2461 path_converter, &path,
2462#ifdef HAVE_FSTATAT
2463 dir_fd_converter, &dir_fd,
2464#else
2465 dir_fd_unavailable, &dir_fd,
2466#endif
2467 &follow_symlinks))
2468 return NULL;
2469 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2470 path_cleanup(&path);
2471 return return_value;
2472}
2473
2474PyDoc_STRVAR(posix_lstat__doc__,
2475"lstat(path, *, dir_fd=None) -> stat result\n\n\
2476Like stat(), but do not follow symbolic links.\n\
2477Equivalent to stat(path, follow_symlinks=False).");
2478
2479static PyObject *
2480posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
2481{
2482 static char *keywords[] = {"path", "dir_fd", NULL};
2483 path_t path;
2484 int dir_fd = DEFAULT_DIR_FD;
2485 int follow_symlinks = 0;
2486 PyObject *return_value;
2487
2488 memset(&path, 0, sizeof(path));
2489 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
2490 path_converter, &path,
2491#ifdef HAVE_FSTATAT
2492 dir_fd_converter, &dir_fd
2493#else
2494 dir_fd_unavailable, &dir_fd
2495#endif
2496 ))
2497 return NULL;
2498 return_value = posix_do_stat("stat", &path, dir_fd, follow_symlinks);
2499 path_cleanup(&path);
2500 return return_value;
2501}
2502
2503PyDoc_STRVAR(posix_access__doc__,
2504"access(path, mode, *, dir_fd=None, effective_ids=False,\
2505 follow_symlinks=True)\n\n\
2506Use the real uid/gid to test for access to a path. Returns True if granted,\n\
2507False otherwise.\n\
2508\n\
2509If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2510 and path should be relative; path will then be relative to that directory.\n\
2511If effective_ids is True, access will use the effective uid/gid instead of\n\
2512 the real uid/gid.\n\
2513If follow_symlinks is False, and the last element of the path is a symbolic\n\
2514 link, access will examine the symbolic link itself instead of the file the\n\
2515 link points to.\n\
2516dir_fd, effective_ids, and follow_symlinks may not be implemented\n\
2517 on your platform. If they are unavailable, using them will raise a\n\
2518 NotImplementedError.\n\
2519\n\
2520Note that most operations will use the effective uid/gid, therefore this\n\
2521 routine can be used in a suid/sgid environment to test if the invoking user\n\
2522 has the specified access to the path.\n\
2523The mode argument can be F_OK to test existence, or the inclusive-OR\n\
2524 of R_OK, W_OK, and X_OK.");
2525
2526static PyObject *
2527posix_access(PyObject *self, PyObject *args, PyObject *kwargs)
2528{
2529 static char *keywords[] = {"path", "mode", "dir_fd", "effective_ids",
2530 "follow_symlinks", NULL};
2531 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002532 int mode;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002533 int dir_fd = DEFAULT_DIR_FD;
2534 int effective_ids = 0;
2535 int follow_symlinks = 1;
2536 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002537
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002538#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002539 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002540#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002542#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002543
2544 memset(&path, 0, sizeof(path));
2545 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", keywords,
2546 path_converter, &path, &mode,
2547#ifdef HAVE_FACCESSAT
2548 dir_fd_converter, &dir_fd,
2549#else
2550 dir_fd_unavailable, &dir_fd,
2551#endif
2552 &effective_ids, &follow_symlinks))
2553 return NULL;
2554
2555#ifndef HAVE_FACCESSAT
2556 if (follow_symlinks_specified("access", follow_symlinks))
2557 goto exit;
2558
2559 if (effective_ids) {
2560 argument_unavailable_error("access", "effective_ids");
2561 goto exit;
2562 }
2563#endif
2564
2565#ifdef MS_WINDOWS
2566 Py_BEGIN_ALLOW_THREADS
2567 if (path.wide != NULL)
2568 attr = GetFileAttributesW(path.wide);
2569 else
2570 attr = GetFileAttributesA(path.narrow);
2571 Py_END_ALLOW_THREADS
2572
2573 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002574 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 * * we didn't get a -1, and
2576 * * write access wasn't requested,
2577 * * or the file isn't read-only,
2578 * * or it's a directory.
2579 * (Directories cannot be read-only on Windows.)
2580 */
2581 return_value = PyBool_FromLong(
2582 (attr != 0xFFFFFFFF) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002583 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 !(attr & FILE_ATTRIBUTE_READONLY) ||
2585 (attr & FILE_ATTRIBUTE_DIRECTORY)));
2586#else
2587
2588 Py_BEGIN_ALLOW_THREADS
2589#ifdef HAVE_FACCESSAT
2590 if ((dir_fd != DEFAULT_DIR_FD) ||
2591 effective_ids ||
2592 !follow_symlinks) {
2593 int flags = 0;
2594 if (!follow_symlinks)
2595 flags |= AT_SYMLINK_NOFOLLOW;
2596 if (effective_ids)
2597 flags |= AT_EACCESS;
2598 result = faccessat(dir_fd, path.narrow, mode, flags);
2599 }
2600 else
2601#endif
2602 result = access(path.narrow, mode);
2603 Py_END_ALLOW_THREADS
2604 return_value = PyBool_FromLong(!result);
2605#endif
2606
2607#ifndef HAVE_FACCESSAT
2608exit:
2609#endif
2610 path_cleanup(&path);
2611 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002612}
2613
Guido van Rossumd371ff11999-01-25 16:12:23 +00002614#ifndef F_OK
2615#define F_OK 0
2616#endif
2617#ifndef R_OK
2618#define R_OK 4
2619#endif
2620#ifndef W_OK
2621#define W_OK 2
2622#endif
2623#ifndef X_OK
2624#define X_OK 1
2625#endif
2626
2627#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002628PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002629"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002630Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002631
2632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002633posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002634{
Victor Stinner8c62be82010-05-06 00:08:46 +00002635 int id;
2636 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002637
Victor Stinner8c62be82010-05-06 00:08:46 +00002638 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2639 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002640
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002641#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 /* file descriptor 0 only, the default input device (stdin) */
2643 if (id == 0) {
2644 ret = ttyname();
2645 }
2646 else {
2647 ret = NULL;
2648 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002649#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002650 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002651#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 if (ret == NULL)
2653 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002654 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002655}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002656#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002657
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002658#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002659PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002660"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002662
2663static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002664posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002665{
Victor Stinner8c62be82010-05-06 00:08:46 +00002666 char *ret;
2667 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002668
Greg Wardb48bc172000-03-01 21:51:56 +00002669#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002670 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002673#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002674 if (ret == NULL)
2675 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002676 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002677}
2678#endif
2679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002680PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002681"chdir(path)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002682Change the current working directory to the specified path.\n\
2683\n\
2684path may always be specified as a string.\n\
2685On some platforms, path may also be specified as an open file descriptor.\n\
2686 If this functionality is unavailable, using it raises an exception.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002687
Barry Warsaw53699e91996-12-10 23:23:01 +00002688static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002689posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002690{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002691 path_t path;
2692 int result;
2693 PyObject *return_value = NULL;
2694 static char *keywords[] = {"path", NULL};
2695
2696 memset(&path, 0, sizeof(path));
2697#ifdef HAVE_FCHDIR
2698 path.allow_fd = 1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002699#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002700 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords,
2701 path_converter, &path
2702 ))
2703 return NULL;
2704
2705 Py_BEGIN_ALLOW_THREADS
2706#ifdef MS_WINDOWS
2707 if (path.wide)
2708 result = win32_wchdir(path.wide);
2709 else
2710 result = win32_chdir(path.narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002711 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712#elif defined(PYOS_OS2) && defined(PYCC_GCC)
2713 result = _chdir2(path.narrow);
2714#else
2715#ifdef HAVE_FCHDIR
2716 if (path.fd != -1)
2717 result = fchdir(path.fd);
2718 else
2719#endif
2720 result = chdir(path.narrow);
2721#endif
2722 Py_END_ALLOW_THREADS
2723
2724 if (result) {
2725 return_value = path_error("chdir", &path);
2726 goto exit;
2727 }
2728
2729 return_value = Py_None;
2730 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02002731
Larry Hastings9cf065c2012-06-22 16:30:09 -07002732exit:
2733 path_cleanup(&path);
2734 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002735}
2736
Fred Drake4d1e64b2002-04-15 19:40:07 +00002737#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002738PyDoc_STRVAR(posix_fchdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002739"fchdir(fd)\n\n\
2740Change to the directory of the given file descriptor. fd must be\n\
2741opened on a directory, not a file. Equivalent to os.chdir(fd).");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002742
2743static PyObject *
2744posix_fchdir(PyObject *self, PyObject *fdobj)
2745{
Victor Stinner8c62be82010-05-06 00:08:46 +00002746 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002747}
2748#endif /* HAVE_FCHDIR */
2749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002751PyDoc_STRVAR(posix_chmod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002752"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\
2753Change the access permissions of a file.\n\
2754\n\
2755path may always be specified as a string.\n\
2756On some platforms, path may also be specified as an open file descriptor.\n\
2757 If this functionality is unavailable, using it raises an exception.\n\
2758If dir_fd is not None, it should be a file descriptor open to a directory,\n\
2759 and path should be relative; path will then be relative to that directory.\n\
2760If follow_symlinks is False, and the last element of the path is a symbolic\n\
2761 link, chmod will modify the symbolic link itself instead of the file the\n\
2762 link points to.\n\
2763It is an error to use dir_fd or follow_symlinks when specifying path as\n\
2764 an open file descriptor.\n\
2765dir_fd and follow_symlinks may not be implemented on your platform.\n\
2766 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002767
Barry Warsaw53699e91996-12-10 23:23:01 +00002768static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002769posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002770{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771 path_t path;
2772 int mode;
2773 int dir_fd = DEFAULT_DIR_FD;
2774 int follow_symlinks = 1;
2775 int result;
2776 PyObject *return_value = NULL;
2777 static char *keywords[] = {"path", "mode", "dir_fd",
2778 "follow_symlinks", NULL};
2779
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002780#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002781 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002783
Larry Hastings9cf065c2012-06-22 16:30:09 -07002784#ifdef HAVE_FCHMODAT
2785 int fchmodat_nofollow_unsupported = 0;
2786#endif
2787
2788 memset(&path, 0, sizeof(path));
2789#ifdef HAVE_FCHMOD
2790 path.allow_fd = 1;
2791#endif
2792 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords,
2793 path_converter, &path,
2794 &mode,
2795#ifdef HAVE_FCHMODAT
2796 dir_fd_converter, &dir_fd,
2797#else
2798 dir_fd_unavailable, &dir_fd,
2799#endif
2800 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802
2803#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2804 if (follow_symlinks_specified("chmod", follow_symlinks))
2805 goto exit;
2806#endif
2807
2808#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002809 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810 if (path.wide)
2811 attr = GetFileAttributesW(path.wide);
2812 else
2813 attr = GetFileAttributesA(path.narrow);
2814 if (attr == 0xFFFFFFFF)
2815 result = 0;
2816 else {
2817 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 attr &= ~FILE_ATTRIBUTE_READONLY;
2819 else
2820 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002821 if (path.wide)
2822 result = SetFileAttributesW(path.wide, attr);
2823 else
2824 result = SetFileAttributesA(path.narrow, attr);
2825 }
2826 Py_END_ALLOW_THREADS
2827
2828 if (!result) {
2829 return_value = win32_error_object("chmod", path.object);
2830 goto exit;
2831 }
2832#else /* MS_WINDOWS */
2833 Py_BEGIN_ALLOW_THREADS
2834#ifdef HAVE_FCHMOD
2835 if (path.fd != -1)
2836 result = fchmod(path.fd, mode);
2837 else
2838#endif
2839#ifdef HAVE_LCHMOD
2840 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2841 result = lchmod(path.narrow, mode);
2842 else
2843#endif
2844#ifdef HAVE_FCHMODAT
2845 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2846 /*
2847 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2848 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002849 * and then says it isn't implemented yet.
2850 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851 *
2852 * Once it is supported, os.chmod will automatically
2853 * support dir_fd and follow_symlinks=False. (Hopefully.)
2854 * Until then, we need to be careful what exception we raise.
2855 */
2856 result = fchmodat(dir_fd, path.narrow, mode,
2857 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2858 /*
2859 * But wait! We can't throw the exception without allowing threads,
2860 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2861 */
2862 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002863 result &&
2864 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2865 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002866 }
2867 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002868#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869 result = chmod(path.narrow, mode);
2870 Py_END_ALLOW_THREADS
2871
2872 if (result) {
2873#ifdef HAVE_FCHMODAT
2874 if (fchmodat_nofollow_unsupported) {
2875 if (dir_fd != DEFAULT_DIR_FD)
2876 dir_fd_and_follow_symlinks_invalid("chmod",
2877 dir_fd, follow_symlinks);
2878 else
2879 follow_symlinks_specified("chmod", follow_symlinks);
2880 }
2881 else
2882#endif
2883 return_value = path_error("chmod", &path);
2884 goto exit;
2885 }
2886#endif
2887
2888 Py_INCREF(Py_None);
2889 return_value = Py_None;
2890exit:
2891 path_cleanup(&path);
2892 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002893}
2894
Larry Hastings9cf065c2012-06-22 16:30:09 -07002895
Christian Heimes4e30a842007-11-30 22:12:06 +00002896#ifdef HAVE_FCHMOD
2897PyDoc_STRVAR(posix_fchmod__doc__,
2898"fchmod(fd, mode)\n\n\
2899Change the access permissions of the file given by file\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002900descriptor fd. Equivalent to os.chmod(fd, mode).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002901
2902static PyObject *
2903posix_fchmod(PyObject *self, PyObject *args)
2904{
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 int fd, mode, res;
2906 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2907 return NULL;
2908 Py_BEGIN_ALLOW_THREADS
2909 res = fchmod(fd, mode);
2910 Py_END_ALLOW_THREADS
2911 if (res < 0)
2912 return posix_error();
2913 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002914}
2915#endif /* HAVE_FCHMOD */
2916
2917#ifdef HAVE_LCHMOD
2918PyDoc_STRVAR(posix_lchmod__doc__,
2919"lchmod(path, mode)\n\n\
2920Change the access permissions of a file. If path is a symlink, this\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07002921affects the link itself rather than the target.\n\
2922Equivalent to chmod(path, mode, follow_symlinks=False).");
Christian Heimes4e30a842007-11-30 22:12:06 +00002923
2924static PyObject *
2925posix_lchmod(PyObject *self, PyObject *args)
2926{
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 PyObject *opath;
2928 char *path;
2929 int i;
2930 int res;
2931 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2932 &opath, &i))
2933 return NULL;
2934 path = PyBytes_AsString(opath);
2935 Py_BEGIN_ALLOW_THREADS
2936 res = lchmod(path, i);
2937 Py_END_ALLOW_THREADS
2938 if (res < 0)
2939 return posix_error_with_allocated_filename(opath);
2940 Py_DECREF(opath);
2941 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002942}
2943#endif /* HAVE_LCHMOD */
2944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002945
Thomas Wouterscf297e42007-02-23 15:07:44 +00002946#ifdef HAVE_CHFLAGS
2947PyDoc_STRVAR(posix_chflags__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002948"chflags(path, flags, *, follow_symlinks=True)\n\n\
2949Set file flags.\n\
2950\n\
2951If follow_symlinks is False, and the last element of the path is a symbolic\n\
2952 link, chflags will change flags on the symbolic link itself instead of the\n\
2953 file the link points to.\n\
2954follow_symlinks may not be implemented on your platform. If it is\n\
2955unavailable, using it will raise a NotImplementedError.");
Thomas Wouterscf297e42007-02-23 15:07:44 +00002956
2957static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002958posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouterscf297e42007-02-23 15:07:44 +00002959{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002960 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002961 unsigned long flags;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002962 int follow_symlinks = 1;
2963 int result;
2964 PyObject *return_value;
2965 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
2966
2967 memset(&path, 0, sizeof(path));
2968 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
2969 path_converter, &path,
2970 &flags, &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972
2973#ifndef HAVE_LCHFLAGS
2974 if (follow_symlinks_specified("chflags", follow_symlinks))
2975 goto exit;
2976#endif
2977
Victor Stinner8c62be82010-05-06 00:08:46 +00002978 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979#ifdef HAVE_LCHFLAGS
2980 if (!follow_symlinks)
2981 result = lchflags(path.narrow, flags);
2982 else
2983#endif
2984 result = chflags(path.narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002985 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002986
2987 if (result) {
2988 return_value = path_posix_error("chflags", &path);
2989 goto exit;
2990 }
2991
2992 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994
2995exit:
2996 path_cleanup(&path);
2997 return return_value;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002998}
2999#endif /* HAVE_CHFLAGS */
3000
3001#ifdef HAVE_LCHFLAGS
3002PyDoc_STRVAR(posix_lchflags__doc__,
3003"lchflags(path, flags)\n\n\
3004Set file flags.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003005This function will not follow symbolic links.\n\
3006Equivalent to chflags(path, flags, follow_symlinks=False).");
Thomas Wouterscf297e42007-02-23 15:07:44 +00003007
3008static PyObject *
3009posix_lchflags(PyObject *self, PyObject *args)
3010{
Victor Stinner8c62be82010-05-06 00:08:46 +00003011 PyObject *opath;
3012 char *path;
3013 unsigned long flags;
3014 int res;
3015 if (!PyArg_ParseTuple(args, "O&k:lchflags",
3016 PyUnicode_FSConverter, &opath, &flags))
3017 return NULL;
3018 path = PyBytes_AsString(opath);
3019 Py_BEGIN_ALLOW_THREADS
3020 res = lchflags(path, flags);
3021 Py_END_ALLOW_THREADS
3022 if (res < 0)
3023 return posix_error_with_allocated_filename(opath);
3024 Py_DECREF(opath);
3025 Py_INCREF(Py_None);
3026 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003027}
3028#endif /* HAVE_LCHFLAGS */
3029
Martin v. Löwis244edc82001-10-04 22:44:26 +00003030#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003032"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003033Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00003034
3035static PyObject *
3036posix_chroot(PyObject *self, PyObject *args)
3037{
Victor Stinner8c62be82010-05-06 00:08:46 +00003038 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00003039}
3040#endif
3041
Guido van Rossum21142a01999-01-08 21:05:37 +00003042#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003043PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003044"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003045force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003046
3047static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003048posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003049{
Stefan Krah0e803b32010-11-26 16:16:47 +00003050 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003051}
3052#endif /* HAVE_FSYNC */
3053
Ross Lagerwall7807c352011-03-17 20:20:30 +02003054#ifdef HAVE_SYNC
3055PyDoc_STRVAR(posix_sync__doc__,
3056"sync()\n\n\
3057Force write of everything to disk.");
3058
3059static PyObject *
3060posix_sync(PyObject *self, PyObject *noargs)
3061{
3062 Py_BEGIN_ALLOW_THREADS
3063 sync();
3064 Py_END_ALLOW_THREADS
3065 Py_RETURN_NONE;
3066}
3067#endif
3068
Guido van Rossum21142a01999-01-08 21:05:37 +00003069#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00003070
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003071#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003072extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3073#endif
3074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003075PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003076"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00003077force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003078 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00003079
3080static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00003081posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00003082{
Stefan Krah0e803b32010-11-26 16:16:47 +00003083 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003084}
3085#endif /* HAVE_FDATASYNC */
3086
3087
Fredrik Lundh10723342000-07-10 16:38:09 +00003088#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003089PyDoc_STRVAR(posix_chown__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003090"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\
3091Change the owner and group id of path to the numeric uid and gid.\n\
3092\n\
3093path may always be specified as a string.\n\
3094On some platforms, path may also be specified as an open file descriptor.\n\
3095 If this functionality is unavailable, using it raises an exception.\n\
3096If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3097 and path should be relative; path will then be relative to that directory.\n\
3098If follow_symlinks is False, and the last element of the path is a symbolic\n\
3099 link, chown will modify the symbolic link itself instead of the file the\n\
3100 link points to.\n\
3101It is an error to use dir_fd or follow_symlinks when specifying path as\n\
3102 an open file descriptor.\n\
3103dir_fd and follow_symlinks may not be implemented on your platform.\n\
3104 If they are unavailable, using them will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003105
Barry Warsaw53699e91996-12-10 23:23:01 +00003106static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003107posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003108{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003109 path_t path;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110 uid_t uid;
3111 gid_t gid;
3112 int dir_fd = DEFAULT_DIR_FD;
3113 int follow_symlinks = 1;
3114 int result;
3115 PyObject *return_value = NULL;
3116 static char *keywords[] = {"path", "uid", "gid", "dir_fd",
3117 "follow_symlinks", NULL};
3118
3119 memset(&path, 0, sizeof(path));
3120#ifdef HAVE_FCHOWN
3121 path.allow_fd = 1;
3122#endif
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003123 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003124 path_converter, &path,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003125 _Py_Uid_Converter, &uid,
3126 _Py_Gid_Converter, &gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003127#ifdef HAVE_FCHOWNAT
3128 dir_fd_converter, &dir_fd,
3129#else
3130 dir_fd_unavailable, &dir_fd,
3131#endif
3132 &follow_symlinks))
Victor Stinner8c62be82010-05-06 00:08:46 +00003133 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003134
3135#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3136 if (follow_symlinks_specified("chown", follow_symlinks))
3137 goto exit;
3138#endif
3139 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) ||
3140 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks))
3141 goto exit;
3142
3143#ifdef __APPLE__
3144 /*
3145 * This is for Mac OS X 10.3, which doesn't have lchown.
3146 * (But we still have an lchown symbol because of weak-linking.)
3147 * It doesn't have fchownat either. So there's no possibility
3148 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003149 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003150 if ((!follow_symlinks) && (lchown == NULL)) {
3151 follow_symlinks_specified("chown", follow_symlinks);
3152 goto exit;
3153 }
3154#endif
3155
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157#ifdef HAVE_FCHOWN
3158 if (path.fd != -1)
3159 result = fchown(path.fd, uid, gid);
3160 else
3161#endif
3162#ifdef HAVE_LCHOWN
3163 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
3164 result = lchown(path.narrow, uid, gid);
3165 else
3166#endif
3167#ifdef HAVE_FCHOWNAT
3168 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
3169 result = fchownat(dir_fd, path.narrow, uid, gid,
3170 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3171 else
3172#endif
3173 result = chown(path.narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003174 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175
3176 if (result) {
3177 return_value = path_posix_error("chown", &path);
3178 goto exit;
3179 }
3180
3181 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003183
3184exit:
3185 path_cleanup(&path);
3186 return return_value;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003187}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003188#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003189
Christian Heimes4e30a842007-11-30 22:12:06 +00003190#ifdef HAVE_FCHOWN
3191PyDoc_STRVAR(posix_fchown__doc__,
3192"fchown(fd, uid, gid)\n\n\
3193Change the owner and group id of the file given by file descriptor\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid).");
Christian Heimes4e30a842007-11-30 22:12:06 +00003195
3196static PyObject *
3197posix_fchown(PyObject *self, PyObject *args)
3198{
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 int fd;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003200 uid_t uid;
3201 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003203 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
3204 _Py_Uid_Converter, &uid,
3205 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003206 return NULL;
3207 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003208 res = fchown(fd, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003209 Py_END_ALLOW_THREADS
3210 if (res < 0)
3211 return posix_error();
3212 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003213}
3214#endif /* HAVE_FCHOWN */
3215
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003216#ifdef HAVE_LCHOWN
3217PyDoc_STRVAR(posix_lchown__doc__,
3218"lchown(path, uid, gid)\n\n\
3219Change the owner and group id of path to the numeric uid and gid.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003220This function will not follow symbolic links.\n\
3221Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003222
3223static PyObject *
3224posix_lchown(PyObject *self, PyObject *args)
3225{
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 PyObject *opath;
3227 char *path;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003228 uid_t uid;
3229 gid_t gid;
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003231 if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 PyUnicode_FSConverter, &opath,
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003233 _Py_Uid_Converter, &uid,
3234 _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 return NULL;
3236 path = PyBytes_AsString(opath);
3237 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02003238 res = lchown(path, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 Py_END_ALLOW_THREADS
3240 if (res < 0)
3241 return posix_error_with_allocated_filename(opath);
3242 Py_DECREF(opath);
3243 Py_INCREF(Py_None);
3244 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003245}
3246#endif /* HAVE_LCHOWN */
3247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003248
Guido van Rossum36bc6801995-06-14 22:54:23 +00003249#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00003250static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003251posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003252{
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 char buf[1026];
3254 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003255
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003256#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003257 if (!use_bytes) {
3258 wchar_t wbuf[1026];
3259 wchar_t *wbuf2 = wbuf;
3260 PyObject *resobj;
3261 DWORD len;
3262 Py_BEGIN_ALLOW_THREADS
3263 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
3264 /* If the buffer is large enough, len does not include the
3265 terminating \0. If the buffer is too small, len includes
3266 the space needed for the terminator. */
3267 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
3268 wbuf2 = malloc(len * sizeof(wchar_t));
3269 if (wbuf2)
3270 len = GetCurrentDirectoryW(len, wbuf2);
3271 }
3272 Py_END_ALLOW_THREADS
3273 if (!wbuf2) {
3274 PyErr_NoMemory();
3275 return NULL;
3276 }
3277 if (!len) {
3278 if (wbuf2 != wbuf) free(wbuf2);
3279 return win32_error("getcwdu", NULL);
3280 }
3281 resobj = PyUnicode_FromWideChar(wbuf2, len);
3282 if (wbuf2 != wbuf) free(wbuf2);
3283 return resobj;
3284 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003285
3286 if (win32_warn_bytes_api())
3287 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003288#endif
3289
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003291#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003293#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003295#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 Py_END_ALLOW_THREADS
3297 if (res == NULL)
3298 return posix_error();
3299 if (use_bytes)
3300 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003301 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003302}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003303
3304PyDoc_STRVAR(posix_getcwd__doc__,
3305"getcwd() -> path\n\n\
3306Return a unicode string representing the current working directory.");
3307
3308static PyObject *
3309posix_getcwd_unicode(PyObject *self)
3310{
3311 return posix_getcwd(0);
3312}
3313
3314PyDoc_STRVAR(posix_getcwdb__doc__,
3315"getcwdb() -> path\n\n\
3316Return a bytes string representing the current working directory.");
3317
3318static PyObject *
3319posix_getcwd_bytes(PyObject *self)
3320{
3321 return posix_getcwd(1);
3322}
Guido van Rossum36bc6801995-06-14 22:54:23 +00003323#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003324
Larry Hastings9cf065c2012-06-22 16:30:09 -07003325#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3326#define HAVE_LINK 1
3327#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003328
Guido van Rossumb6775db1994-08-01 11:34:53 +00003329#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003330PyDoc_STRVAR(posix_link__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003331"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\
3332Create a hard link to a file.\n\
3333\n\
3334If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
3335 descriptor open to a directory, and the respective path string (src or dst)\n\
3336 should be relative; the path will then be relative to that directory.\n\
3337If follow_symlinks is False, and the last element of src is a symbolic\n\
3338 link, link will create a link to the symbolic link itself instead of the\n\
3339 file the link points to.\n\
3340src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\
3341 platform. If they are unavailable, using them will raise a\n\
3342 NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003343
Barry Warsaw53699e91996-12-10 23:23:01 +00003344static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003345posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003346{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003347 path_t src, dst;
3348 int src_dir_fd = DEFAULT_DIR_FD;
3349 int dst_dir_fd = DEFAULT_DIR_FD;
3350 int follow_symlinks = 1;
3351 PyObject *return_value = NULL;
3352 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd",
3353 "follow_symlinks", NULL};
3354#ifdef MS_WINDOWS
3355 BOOL result;
3356#else
3357 int result;
3358#endif
3359
3360 memset(&src, 0, sizeof(src));
3361 memset(&dst, 0, sizeof(dst));
3362 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
3363 path_converter, &src,
3364 path_converter, &dst,
3365 dir_fd_converter, &src_dir_fd,
3366 dir_fd_converter, &dst_dir_fd,
3367 &follow_symlinks))
3368 return NULL;
3369
3370#ifndef HAVE_LINKAT
3371 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3372 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
3373 goto exit;
3374 }
3375#endif
3376
3377 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
3378 PyErr_SetString(PyExc_NotImplementedError,
3379 "link: src and dst must be the same type");
3380 goto exit;
3381 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003382
Brian Curtin1b9df392010-11-24 20:24:31 +00003383#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003384 Py_BEGIN_ALLOW_THREADS
3385 if (src.wide)
3386 result = CreateHardLinkW(dst.wide, src.wide, NULL);
3387 else
3388 result = CreateHardLinkA(dst.narrow, src.narrow, NULL);
3389 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003390
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 if (!result) {
3392 return_value = win32_error_object("link", dst.object);
3393 goto exit;
Brian Curtinfc889c42010-11-28 23:59:46 +00003394 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003395#else
3396 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003397#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003398 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3399 (dst_dir_fd != DEFAULT_DIR_FD) ||
3400 (!follow_symlinks))
3401 result = linkat(src_dir_fd, src.narrow,
3402 dst_dir_fd, dst.narrow,
3403 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3404 else
3405#endif
3406 result = link(src.narrow, dst.narrow);
3407 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003408
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409 if (result) {
3410 return_value = path_error("link", &dst);
3411 goto exit;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003412 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413#endif
3414
3415 return_value = Py_None;
3416 Py_INCREF(Py_None);
3417
3418exit:
3419 path_cleanup(&src);
3420 path_cleanup(&dst);
3421 return return_value;
Brian Curtin1b9df392010-11-24 20:24:31 +00003422}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423#endif
3424
Brian Curtin1b9df392010-11-24 20:24:31 +00003425
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003426
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003427PyDoc_STRVAR(posix_listdir__doc__,
Larry Hastingsfdaea062012-06-25 04:42:23 -07003428"listdir(path='.') -> list_of_filenames\n\n\
3429Return a list containing the names of the files in the directory.\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003430The list is in arbitrary order. It does not include the special\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431entries '.' and '..' even if they are present in the directory.\n\
3432\n\
Larry Hastingsfdaea062012-06-25 04:42:23 -07003433path can be specified as either str or bytes. If path is bytes,\n\
3434 the filenames returned will also be bytes; in all other circumstances\n\
3435 the filenames returned will be str.\n\
3436On some platforms, path may also be specified as an open file descriptor;\n\
3437 the file descriptor must refer to a directory.\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003439
Barry Warsaw53699e91996-12-10 23:23:01 +00003440static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003442{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 path_t path;
3444 PyObject *list = NULL;
3445 static char *keywords[] = {"path", NULL};
3446 int fd = -1;
3447
3448#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3449 PyObject *v;
3450 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3451 BOOL result;
3452 WIN32_FIND_DATA FileData;
3453 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
3454 char *bufptr = namebuf;
3455 /* only claim to have space for MAX_PATH */
3456 Py_ssize_t len = sizeof(namebuf)-5;
3457 PyObject *po = NULL;
3458 wchar_t *wnamebuf = NULL;
3459#elif defined(PYOS_OS2)
3460#ifndef MAX_PATH
3461#define MAX_PATH CCHMAXPATH
3462#endif
3463 char *pt;
3464 PyObject *v;
3465 char namebuf[MAX_PATH+5];
3466 HDIR hdir = 1;
3467 ULONG srchcnt = 1;
3468 FILEFINDBUF3 ep;
3469 APIRET rc;
3470#else
3471 PyObject *v;
3472 DIR *dirp = NULL;
3473 struct dirent *ep;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003474 int return_str; /* if false, return bytes */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475#endif
3476
3477 memset(&path, 0, sizeof(path));
3478 path.nullable = 1;
3479#ifdef HAVE_FDOPENDIR
3480 path.allow_fd = 1;
3481 path.fd = -1;
3482#endif
3483 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords,
3484 path_converter, &path
3485 ))
3486 return NULL;
3487
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 /* XXX Should redo this putting the (now four) versions of opendir
3489 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003490#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 if (!path.narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003494
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 if (!path.wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003496 po_wchars = L".";
3497 len = 1;
3498 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499 po_wchars = path.wide;
3500 len = wcslen(path.wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003501 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003502 /* The +5 is so we can append "\\*.*\0" */
Victor Stinner8c62be82010-05-06 00:08:46 +00003503 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
3504 if (!wnamebuf) {
3505 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003508 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003510 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 if (wch != L'/' && wch != L'\\' && wch != L':')
3512 wnamebuf[len++] = L'\\';
3513 wcscpy(wnamebuf + len, L"*.*");
3514 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003515 if ((list = PyList_New(0)) == NULL) {
3516 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003518 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003520 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 if (hFindFile == INVALID_HANDLE_VALUE) {
3522 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 if (error == ERROR_FILE_NOT_FOUND)
3524 goto exit;
3525 Py_DECREF(list);
3526 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 win32_error_unicode("FindFirstFileW", wnamebuf);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 }
3530 do {
3531 /* Skip over . and .. */
3532 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3533 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534 v = PyUnicode_FromWideChar(wFileData.cFileName,
3535 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 Py_DECREF(list);
3538 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 break;
3540 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 Py_DECREF(list);
3544 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 break;
3546 }
3547 Py_DECREF(v);
3548 }
3549 Py_BEGIN_ALLOW_THREADS
3550 result = FindNextFileW(hFindFile, &wFileData);
3551 Py_END_ALLOW_THREADS
3552 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3553 it got to the end of the directory. */
3554 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 Py_DECREF(list);
3556 list = win32_error_unicode("FindNextFileW", wnamebuf);
3557 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 }
3559 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003560
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 strcpy(namebuf, path.narrow);
3564 len = path.length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 if (len > 0) {
3566 char ch = namebuf[len-1];
3567 if (ch != SEP && ch != ALTSEP && ch != ':')
3568 namebuf[len++] = '/';
3569 strcpy(namebuf + len, "*.*");
3570 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003571
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003574
Antoine Pitroub73caab2010-08-09 23:39:31 +00003575 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003577 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 if (hFindFile == INVALID_HANDLE_VALUE) {
3579 int error = GetLastError();
3580 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 goto exit;
3582 Py_DECREF(list);
3583 list = win32_error("FindFirstFile", namebuf);
3584 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 }
3586 do {
3587 /* Skip over . and .. */
3588 if (strcmp(FileData.cFileName, ".") != 0 &&
3589 strcmp(FileData.cFileName, "..") != 0) {
3590 v = PyBytes_FromString(FileData.cFileName);
3591 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 Py_DECREF(list);
3593 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 break;
3595 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003597 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 Py_DECREF(list);
3599 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 break;
3601 }
3602 Py_DECREF(v);
3603 }
3604 Py_BEGIN_ALLOW_THREADS
3605 result = FindNextFile(hFindFile, &FileData);
3606 Py_END_ALLOW_THREADS
3607 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3608 it got to the end of the directory. */
3609 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610 Py_DECREF(list);
3611 list = win32_error("FindNextFile", namebuf);
3612 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 }
3614 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003615
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616exit:
3617 if (hFindFile != INVALID_HANDLE_VALUE) {
3618 if (FindClose(hFindFile) == FALSE) {
3619 if (list != NULL) {
3620 Py_DECREF(list);
3621 list = win32_error_object("FindClose", path.object);
3622 }
3623 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003624 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 if (wnamebuf)
3626 free(wnamebuf);
3627 path_cleanup(&path);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003628
Larry Hastings9cf065c2012-06-22 16:30:09 -07003629 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003630
Tim Peters0bb44a42000-09-15 07:44:49 +00003631#elif defined(PYOS_OS2)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 if (path.length >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00003633 PyErr_SetString(PyExc_ValueError, "path too long");
Larry Hastings9cf065c2012-06-22 16:30:09 -07003634 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003635 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 strcpy(namebuf, path.narrow);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003637 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003638 if (*pt == ALTSEP)
3639 *pt = SEP;
3640 if (namebuf[len-1] != SEP)
3641 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003642 strcpy(namebuf + len, "*.*");
3643
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644 if ((list = PyList_New(0)) == NULL) {
3645 goto exit;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00003646 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003647
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003648 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
3649 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003650 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003651 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
3652 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
3653 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003654
3655 if (rc != NO_ERROR) {
3656 errno = ENOENT;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003657 Py_DECREF(list);
3658 list = posix_error_with_filename(path.narrow);
3659 goto exit;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003660 }
3661
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003662 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003663 do {
3664 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003665 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003666 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003667
3668 strcpy(namebuf, ep.achName);
3669
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003670 /* Leave Case of Name Alone -- In Native Form */
3671 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003672
Christian Heimes72b710a2008-05-26 13:28:38 +00003673 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003674 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003675 Py_DECREF(list);
3676 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003677 break;
3678 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 if (PyList_Append(list, v) != 0) {
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003680 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 Py_DECREF(list);
3682 list = NULL;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003683 break;
3684 }
3685 Py_DECREF(v);
3686 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
3687 }
3688
Larry Hastings9cf065c2012-06-22 16:30:09 -07003689exit:
3690 path_cleanup(&path);
3691
3692 return list;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003693#else
Just van Rossum96b1c902003-03-03 17:32:15 +00003694
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696#ifdef HAVE_FDOPENDIR
3697 if (path.fd != -1) {
3698 /* closedir() closes the FD, so we duplicate it */
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003699 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003700 fd = dup(path.fd);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00003701 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003702
3703 if (fd == -1) {
3704 list = posix_error();
3705 goto exit;
3706 }
3707
Larry Hastingsfdaea062012-06-25 04:42:23 -07003708 return_str = 1;
3709
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 Py_BEGIN_ALLOW_THREADS
3711 dirp = fdopendir(fd);
3712 Py_END_ALLOW_THREADS
3713 }
3714 else
3715#endif
3716 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003717 char *name;
3718 if (path.narrow) {
3719 name = path.narrow;
3720 /* only return bytes if they specified a bytes object */
3721 return_str = !(PyBytes_Check(path.object));
3722 }
3723 else {
3724 name = ".";
3725 return_str = 1;
3726 }
3727
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 Py_BEGIN_ALLOW_THREADS
3729 dirp = opendir(name);
3730 Py_END_ALLOW_THREADS
3731 }
3732
3733 if (dirp == NULL) {
3734 list = path_error("listdir", &path);
3735 goto exit;
3736 }
3737 if ((list = PyList_New(0)) == NULL) {
3738 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 }
3740 for (;;) {
3741 errno = 0;
3742 Py_BEGIN_ALLOW_THREADS
3743 ep = readdir(dirp);
3744 Py_END_ALLOW_THREADS
3745 if (ep == NULL) {
3746 if (errno == 0) {
3747 break;
3748 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003749 Py_DECREF(list);
3750 list = path_error("listdir", &path);
3751 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 }
3753 }
3754 if (ep->d_name[0] == '.' &&
3755 (NAMLEN(ep) == 1 ||
3756 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3757 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003758 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003759 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3760 else
3761 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003762 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003764 break;
3765 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003766 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003768 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 break;
3770 }
3771 Py_DECREF(v);
3772 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003773
Larry Hastings9cf065c2012-06-22 16:30:09 -07003774exit:
3775 if (dirp != NULL) {
3776 Py_BEGIN_ALLOW_THREADS
3777 if (fd > -1)
3778 rewinddir(dirp);
3779 closedir(dirp);
3780 Py_END_ALLOW_THREADS
3781 }
3782
3783 path_cleanup(&path);
3784
3785 return list;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003786
Tim Peters0bb44a42000-09-15 07:44:49 +00003787#endif /* which OS */
3788} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003789
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003790#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003791/* A helper function for abspath on win32 */
3792static PyObject *
3793posix__getfullpathname(PyObject *self, PyObject *args)
3794{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003795 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003796 char outbuf[MAX_PATH*2];
3797 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003798 PyObject *po;
3799
3800 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3801 {
3802 wchar_t *wpath;
3803 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3804 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003805 DWORD result;
3806 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003807
3808 wpath = PyUnicode_AsUnicode(po);
3809 if (wpath == NULL)
3810 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003811 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003812 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003813 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003814 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003815 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003816 if (!woutbufp)
3817 return PyErr_NoMemory();
3818 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3819 }
3820 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003821 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003822 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003823 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003824 if (woutbufp != woutbuf)
3825 free(woutbufp);
3826 return v;
3827 }
3828 /* Drop the argument parsing error as narrow strings
3829 are also valid. */
3830 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003831
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003832 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3833 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003834 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003835 if (win32_warn_bytes_api())
3836 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003837 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003838 outbuf, &temp)) {
3839 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 return NULL;
3841 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003842 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3843 return PyUnicode_Decode(outbuf, strlen(outbuf),
3844 Py_FileSystemDefaultEncoding, NULL);
3845 }
3846 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003847} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003848
Brian Curtind25aef52011-06-13 15:16:04 -05003849
Brian Curtinf5e76d02010-11-24 13:14:05 +00003850
Brian Curtind40e6f72010-07-08 21:39:08 +00003851/* A helper function for samepath on windows */
3852static PyObject *
3853posix__getfinalpathname(PyObject *self, PyObject *args)
3854{
3855 HANDLE hFile;
3856 int buf_size;
3857 wchar_t *target_path;
3858 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003859 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003860 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003861
Victor Stinnereb5657a2011-09-30 01:44:27 +02003862 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003863 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003864 path = PyUnicode_AsUnicode(po);
3865 if (path == NULL)
3866 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003867
3868 if(!check_GetFinalPathNameByHandle()) {
3869 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3870 NotImplementedError. */
3871 return PyErr_Format(PyExc_NotImplementedError,
3872 "GetFinalPathNameByHandle not available on this platform");
3873 }
3874
3875 hFile = CreateFileW(
3876 path,
3877 0, /* desired access */
3878 0, /* share mode */
3879 NULL, /* security attributes */
3880 OPEN_EXISTING,
3881 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3882 FILE_FLAG_BACKUP_SEMANTICS,
3883 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003884
Victor Stinnereb5657a2011-09-30 01:44:27 +02003885 if(hFile == INVALID_HANDLE_VALUE)
3886 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003887
3888 /* We have a good handle to the target, use it to determine the
3889 target path name. */
3890 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3891
3892 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003893 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003894
3895 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3896 if(!target_path)
3897 return PyErr_NoMemory();
3898
3899 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3900 buf_size, VOLUME_NAME_DOS);
3901 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003902 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003903
3904 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003905 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003906
3907 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003908 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003909 free(target_path);
3910 return result;
3911
3912} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003913
3914static PyObject *
3915posix__getfileinformation(PyObject *self, PyObject *args)
3916{
3917 HANDLE hFile;
3918 BY_HANDLE_FILE_INFORMATION info;
3919 int fd;
3920
3921 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3922 return NULL;
3923
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003924 if (!_PyVerify_fd(fd))
3925 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003926
3927 hFile = (HANDLE)_get_osfhandle(fd);
3928 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003929 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003930
3931 if (!GetFileInformationByHandle(hFile, &info))
3932 return win32_error("_getfileinformation", NULL);
3933
3934 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3935 info.nFileIndexHigh,
3936 info.nFileIndexLow);
3937}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003938
Brian Curtin95d028f2011-06-09 09:10:38 -05003939PyDoc_STRVAR(posix__isdir__doc__,
3940"Return true if the pathname refers to an existing directory.");
3941
Brian Curtin9c669cc2011-06-08 18:17:18 -05003942static PyObject *
3943posix__isdir(PyObject *self, PyObject *args)
3944{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003945 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003946 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003947 DWORD attributes;
3948
3949 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003950 wchar_t *wpath = PyUnicode_AsUnicode(po);
3951 if (wpath == NULL)
3952 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003953
3954 attributes = GetFileAttributesW(wpath);
3955 if (attributes == INVALID_FILE_ATTRIBUTES)
3956 Py_RETURN_FALSE;
3957 goto check;
3958 }
3959 /* Drop the argument parsing error as narrow strings
3960 are also valid. */
3961 PyErr_Clear();
3962
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003963 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003964 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003965 if (win32_warn_bytes_api())
3966 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003967 attributes = GetFileAttributesA(path);
3968 if (attributes == INVALID_FILE_ATTRIBUTES)
3969 Py_RETURN_FALSE;
3970
3971check:
3972 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3973 Py_RETURN_TRUE;
3974 else
3975 Py_RETURN_FALSE;
3976}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003977#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003978
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003979PyDoc_STRVAR(posix_mkdir__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003980"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3981Create a directory.\n\
3982\n\
3983If dir_fd is not None, it should be a file descriptor open to a directory,\n\
3984 and path should be relative; path will then be relative to that directory.\n\
3985dir_fd may not be implemented on your platform.\n\
3986 If it is unavailable, using it will raise a NotImplementedError.\n\
3987\n\
3988The mode argument is ignored on Windows.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003989
Barry Warsaw53699e91996-12-10 23:23:01 +00003990static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07003991posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003992{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003994 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995 int dir_fd = DEFAULT_DIR_FD;
3996 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
3997 PyObject *return_value = NULL;
3998 int result;
3999
4000 memset(&path, 0, sizeof(path));
4001 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
4002 path_converter, &path, &mode,
4003#ifdef HAVE_MKDIRAT
4004 dir_fd_converter, &dir_fd
4005#else
4006 dir_fd_unavailable, &dir_fd
4007#endif
4008 ))
4009 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004010
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004011#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013 if (path.wide)
4014 result = CreateDirectoryW(path.wide, NULL);
4015 else
4016 result = CreateDirectoryA(path.narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004018
Larry Hastings9cf065c2012-06-22 16:30:09 -07004019 if (!result) {
4020 return_value = win32_error_object("mkdir", path.object);
4021 goto exit;
4022 }
4023#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004025#if HAVE_MKDIRAT
4026 if (dir_fd != DEFAULT_DIR_FD)
4027 result = mkdirat(dir_fd, path.narrow, mode);
4028 else
4029#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004030#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004031 result = mkdir(path.narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004032#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004033 result = mkdir(path.narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004034#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004035 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004036 if (result < 0) {
4037 return_value = path_error("mkdir", &path);
4038 goto exit;
4039 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00004040#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004041 return_value = Py_None;
4042 Py_INCREF(Py_None);
4043exit:
4044 path_cleanup(&path);
4045 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004046}
4047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004048
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004049/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4050#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004051#include <sys/resource.h>
4052#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004053
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004054
4055#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004057"nice(inc) -> new_priority\n\n\
4058Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004059
Barry Warsaw53699e91996-12-10 23:23:01 +00004060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004061posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00004062{
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00004064
Victor Stinner8c62be82010-05-06 00:08:46 +00004065 if (!PyArg_ParseTuple(args, "i:nice", &increment))
4066 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004067
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 /* There are two flavours of 'nice': one that returns the new
4069 priority (as required by almost all standards out there) and the
4070 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4071 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004072
Victor Stinner8c62be82010-05-06 00:08:46 +00004073 If we are of the nice family that returns the new priority, we
4074 need to clear errno before the call, and check if errno is filled
4075 before calling posix_error() on a returnvalue of -1, because the
4076 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004077
Victor Stinner8c62be82010-05-06 00:08:46 +00004078 errno = 0;
4079 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004080#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004081 if (value == 0)
4082 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004083#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004084 if (value == -1 && errno != 0)
4085 /* either nice() or getpriority() returned an error */
4086 return posix_error();
4087 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004088}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004089#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004090
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004091
4092#ifdef HAVE_GETPRIORITY
4093PyDoc_STRVAR(posix_getpriority__doc__,
4094"getpriority(which, who) -> current_priority\n\n\
4095Get program scheduling priority.");
4096
4097static PyObject *
4098posix_getpriority(PyObject *self, PyObject *args)
4099{
4100 int which, who, retval;
4101
4102 if (!PyArg_ParseTuple(args, "ii", &which, &who))
4103 return NULL;
4104 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004105 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004106 if (errno != 0)
4107 return posix_error();
4108 return PyLong_FromLong((long)retval);
4109}
4110#endif /* HAVE_GETPRIORITY */
4111
4112
4113#ifdef HAVE_SETPRIORITY
4114PyDoc_STRVAR(posix_setpriority__doc__,
4115"setpriority(which, who, prio) -> None\n\n\
4116Set program scheduling priority.");
4117
4118static PyObject *
4119posix_setpriority(PyObject *self, PyObject *args)
4120{
4121 int which, who, prio, retval;
4122
4123 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
4124 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004125 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004126 if (retval == -1)
4127 return posix_error();
4128 Py_RETURN_NONE;
4129}
4130#endif /* HAVE_SETPRIORITY */
4131
4132
Barry Warsaw53699e91996-12-10 23:23:01 +00004133static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004135{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136 char *function_name = is_replace ? "replace" : "rename";
4137 path_t src;
4138 path_t dst;
4139 int src_dir_fd = DEFAULT_DIR_FD;
4140 int dst_dir_fd = DEFAULT_DIR_FD;
4141 int dir_fd_specified;
4142 PyObject *return_value = NULL;
4143 char format[24];
4144 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL};
4145
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004146#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004147 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004148 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004149#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004150 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004151#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004152
4153 memset(&src, 0, sizeof(src));
4154 memset(&dst, 0, sizeof(dst));
4155 strcpy(format, "O&O&|$O&O&:");
4156 strcat(format, function_name);
4157 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
4158 path_converter, &src,
4159 path_converter, &dst,
4160 dir_fd_converter, &src_dir_fd,
4161 dir_fd_converter, &dst_dir_fd))
4162 return NULL;
4163
4164 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4165 (dst_dir_fd != DEFAULT_DIR_FD);
4166#ifndef HAVE_RENAMEAT
4167 if (dir_fd_specified) {
4168 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
4169 goto exit;
4170 }
4171#endif
4172
4173 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
4174 PyErr_Format(PyExc_ValueError,
4175 "%s: src and dst must be the same type", function_name);
4176 goto exit;
4177 }
4178
4179#ifdef MS_WINDOWS
4180 Py_BEGIN_ALLOW_THREADS
4181 if (src.wide)
4182 result = MoveFileExW(src.wide, dst.wide, flags);
4183 else
4184 result = MoveFileExA(src.narrow, dst.narrow, flags);
4185 Py_END_ALLOW_THREADS
4186
4187 if (!result) {
4188 return_value = win32_error_object(function_name, dst.object);
4189 goto exit;
4190 }
4191
4192#else
4193 Py_BEGIN_ALLOW_THREADS
4194#ifdef HAVE_RENAMEAT
4195 if (dir_fd_specified)
4196 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow);
4197 else
4198#endif
4199 result = rename(src.narrow, dst.narrow);
4200 Py_END_ALLOW_THREADS
4201
4202 if (result) {
4203 return_value = path_error(function_name, &dst);
4204 goto exit;
4205 }
4206#endif
4207
4208 Py_INCREF(Py_None);
4209 return_value = Py_None;
4210exit:
4211 path_cleanup(&src);
4212 path_cleanup(&dst);
4213 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004214}
4215
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004216PyDoc_STRVAR(posix_rename__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004217"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4218Rename a file or directory.\n\
4219\n\
4220If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4221 descriptor open to a directory, and the respective path string (src or dst)\n\
4222 should be relative; the path will then be relative to that directory.\n\
4223src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4224 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004225
4226static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004227posix_rename(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004228{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004229 return internal_rename(args, kwargs, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004230}
4231
4232PyDoc_STRVAR(posix_replace__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004233"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\
4234Rename a file or directory, overwriting the destination.\n\
4235\n\
4236If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\
4237 descriptor open to a directory, and the respective path string (src or dst)\n\
4238 should be relative; the path will then be relative to that directory.\n\
4239src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\
4240 If they are unavailable, using them will raise a NotImplementedError.");
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004241
4242static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004243posix_replace(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004244{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004245 return internal_rename(args, kwargs, 1);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004246}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004248PyDoc_STRVAR(posix_rmdir__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004249"rmdir(path, *, dir_fd=None)\n\n\
4250Remove a directory.\n\
4251\n\
4252If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4253 and path should be relative; path will then be relative to that directory.\n\
4254dir_fd may not be implemented on your platform.\n\
4255 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004256
Barry Warsaw53699e91996-12-10 23:23:01 +00004257static PyObject *
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004258posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004259{
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004260 path_t path;
4261 int dir_fd = DEFAULT_DIR_FD;
4262 static char *keywords[] = {"path", "dir_fd", NULL};
4263 int result;
4264 PyObject *return_value = NULL;
4265
4266 memset(&path, 0, sizeof(path));
4267 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
4268 path_converter, &path,
4269#ifdef HAVE_UNLINKAT
4270 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004271#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004272 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004273#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004274 ))
4275 return NULL;
4276
4277 Py_BEGIN_ALLOW_THREADS
4278#ifdef MS_WINDOWS
4279 if (path.wide)
4280 result = RemoveDirectoryW(path.wide);
4281 else
4282 result = RemoveDirectoryA(path.narrow);
4283 result = !result; /* Windows, success=1, UNIX, success=0 */
4284#else
4285#ifdef HAVE_UNLINKAT
4286 if (dir_fd != DEFAULT_DIR_FD)
4287 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR);
4288 else
4289#endif
4290 result = rmdir(path.narrow);
4291#endif
4292 Py_END_ALLOW_THREADS
4293
4294 if (result) {
4295 return_value = path_error("rmdir", &path);
4296 goto exit;
4297 }
4298
4299 return_value = Py_None;
4300 Py_INCREF(Py_None);
4301
4302exit:
4303 path_cleanup(&path);
4304 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004305}
4306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004307
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004308#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004309PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004310"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004311Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004312
Barry Warsaw53699e91996-12-10 23:23:01 +00004313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004314posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004315{
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00004317#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004318 wchar_t *command;
4319 if (!PyArg_ParseTuple(args, "u:system", &command))
4320 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004321
Victor Stinner8c62be82010-05-06 00:08:46 +00004322 Py_BEGIN_ALLOW_THREADS
4323 sts = _wsystem(command);
4324 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00004325#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004326 PyObject *command_obj;
4327 char *command;
4328 if (!PyArg_ParseTuple(args, "O&:system",
4329 PyUnicode_FSConverter, &command_obj))
4330 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00004331
Victor Stinner8c62be82010-05-06 00:08:46 +00004332 command = PyBytes_AsString(command_obj);
4333 Py_BEGIN_ALLOW_THREADS
4334 sts = system(command);
4335 Py_END_ALLOW_THREADS
4336 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00004337#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004338 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004339}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004340#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004342
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004343PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004344"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004345Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004346
Barry Warsaw53699e91996-12-10 23:23:01 +00004347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004348posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004349{
Victor Stinner8c62be82010-05-06 00:08:46 +00004350 int i;
4351 if (!PyArg_ParseTuple(args, "i:umask", &i))
4352 return NULL;
4353 i = (int)umask(i);
4354 if (i < 0)
4355 return posix_error();
4356 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004357}
4358
Brian Curtind40e6f72010-07-08 21:39:08 +00004359#ifdef MS_WINDOWS
4360
4361/* override the default DeleteFileW behavior so that directory
4362symlinks can be removed with this function, the same as with
4363Unix symlinks */
4364BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4365{
4366 WIN32_FILE_ATTRIBUTE_DATA info;
4367 WIN32_FIND_DATAW find_data;
4368 HANDLE find_data_handle;
4369 int is_directory = 0;
4370 int is_link = 0;
4371
4372 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4373 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004374
Brian Curtind40e6f72010-07-08 21:39:08 +00004375 /* Get WIN32_FIND_DATA structure for the path to determine if
4376 it is a symlink */
4377 if(is_directory &&
4378 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4379 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4380
4381 if(find_data_handle != INVALID_HANDLE_VALUE) {
4382 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
4383 FindClose(find_data_handle);
4384 }
4385 }
4386 }
4387
4388 if (is_directory && is_link)
4389 return RemoveDirectoryW(lpFileName);
4390
4391 return DeleteFileW(lpFileName);
4392}
4393#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004395PyDoc_STRVAR(posix_unlink__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004396"unlink(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397Remove a file (same as remove()).\n\
4398\n\
4399If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4400 and path should be relative; path will then be relative to that directory.\n\
4401dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004402 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004403
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004404PyDoc_STRVAR(posix_remove__doc__,
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004405"remove(path, *, dir_fd=None)\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07004406Remove a file (same as unlink()).\n\
4407\n\
4408If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4409 and path should be relative; path will then be relative to that directory.\n\
4410dir_fd may not be implemented on your platform.\n\
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004411 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
Barry Warsaw53699e91996-12-10 23:23:01 +00004413static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07004414posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004415{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004416 path_t path;
4417 int dir_fd = DEFAULT_DIR_FD;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004418 static char *keywords[] = {"path", "dir_fd", NULL};
Larry Hastings9cf065c2012-06-22 16:30:09 -07004419 int result;
4420 PyObject *return_value = NULL;
4421
4422 memset(&path, 0, sizeof(path));
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004423 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004424 path_converter, &path,
4425#ifdef HAVE_UNLINKAT
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004426 dir_fd_converter, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004427#else
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004428 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004429#endif
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004430 ))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004431 return NULL;
4432
4433 Py_BEGIN_ALLOW_THREADS
4434#ifdef MS_WINDOWS
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004435 if (path.wide)
4436 result = Py_DeleteFileW(path.wide);
4437 else
4438 result = DeleteFileA(path.narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439 result = !result; /* Windows, success=1, UNIX, success=0 */
4440#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004441#ifdef HAVE_UNLINKAT
4442 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004443 result = unlinkat(dir_fd, path.narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444 else
4445#endif /* HAVE_UNLINKAT */
4446 result = unlink(path.narrow);
4447#endif
4448 Py_END_ALLOW_THREADS
4449
4450 if (result) {
4451 return_value = path_error("unlink", &path);
4452 goto exit;
4453 }
4454
4455 return_value = Py_None;
4456 Py_INCREF(Py_None);
4457
4458exit:
4459 path_cleanup(&path);
4460 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004461}
4462
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004464PyDoc_STRVAR(posix_uname__doc__,
Larry Hastings605a62d2012-06-24 04:33:36 -07004465"uname() -> uname_result\n\n\
4466Return an object identifying the current operating system.\n\
4467The object behaves like a named tuple with the following fields:\n\
4468 (sysname, nodename, release, version, machine)");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004469
Larry Hastings605a62d2012-06-24 04:33:36 -07004470static PyStructSequence_Field uname_result_fields[] = {
4471 {"sysname", "operating system name"},
4472 {"nodename", "name of machine on network (implementation-defined)"},
4473 {"release", "operating system release"},
4474 {"version", "operating system version"},
4475 {"machine", "hardware identifier"},
4476 {NULL}
4477};
4478
4479PyDoc_STRVAR(uname_result__doc__,
4480"uname_result: Result from os.uname().\n\n\
4481This object may be accessed either as a tuple of\n\
4482 (sysname, nodename, release, version, machine),\n\
4483or via the attributes sysname, nodename, release, version, and machine.\n\
4484\n\
4485See os.uname for more information.");
4486
4487static PyStructSequence_Desc uname_result_desc = {
4488 "uname_result", /* name */
4489 uname_result__doc__, /* doc */
4490 uname_result_fields,
4491 5
4492};
4493
4494static PyTypeObject UnameResultType;
4495
4496
4497#ifdef HAVE_UNAME
Barry Warsaw53699e91996-12-10 23:23:01 +00004498static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004499posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004500{
Victor Stinner8c62be82010-05-06 00:08:46 +00004501 struct utsname u;
4502 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004503 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004504
Victor Stinner8c62be82010-05-06 00:08:46 +00004505 Py_BEGIN_ALLOW_THREADS
4506 res = uname(&u);
4507 Py_END_ALLOW_THREADS
4508 if (res < 0)
4509 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004510
4511 value = PyStructSequence_New(&UnameResultType);
4512 if (value == NULL)
4513 return NULL;
4514
4515#define SET(i, field) \
4516 { \
4517 PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \
4518 if (!o) { \
4519 Py_DECREF(value); \
4520 return NULL; \
4521 } \
4522 PyStructSequence_SET_ITEM(value, i, o); \
4523 } \
4524
4525 SET(0, u.sysname);
4526 SET(1, u.nodename);
4527 SET(2, u.release);
4528 SET(3, u.version);
4529 SET(4, u.machine);
4530
4531#undef SET
4532
4533 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004534}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004535#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004536
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004537
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538PyDoc_STRVAR(posix_utime__doc__,
4539"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4540Set the access and modified time of path.\n\
4541\n\
4542path may always be specified as a string.\n\
4543On some platforms, path may also be specified as an open file descriptor.\n\
4544 If this functionality is unavailable, using it raises an exception.\n\
4545\n\
4546If times is not None, it must be a tuple (atime, mtime);\n\
4547 atime and mtime should be expressed as float seconds since the epoch.\n\
4548If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\
4549 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\
4550 since the epoch.\n\
4551If both times and ns are None, utime uses the current time.\n\
4552Specifying tuples for both times and ns is an error.\n\
4553\n\
4554If dir_fd is not None, it should be a file descriptor open to a directory,\n\
4555 and path should be relative; path will then be relative to that directory.\n\
4556If follow_symlinks is False, and the last element of the path is a symbolic\n\
4557 link, utime will modify the symbolic link itself instead of the file the\n\
4558 link points to.\n\
4559It is an error to use dir_fd or follow_symlinks when specifying path\n\
4560 as an open file descriptor.\n\
4561dir_fd and follow_symlinks may not be available on your platform.\n\
4562 If they are unavailable, using them will raise a NotImplementedError.");
4563
4564typedef struct {
4565 int now;
4566 time_t atime_s;
4567 long atime_ns;
4568 time_t mtime_s;
4569 long mtime_ns;
4570} utime_t;
4571
4572/*
4573 * these macros assume that "utime" is a pointer to a utime_t
4574 * they also intentionally leak the declaration of a pointer named "time"
4575 */
4576#define UTIME_TO_TIMESPEC \
4577 struct timespec ts[2]; \
4578 struct timespec *time; \
4579 if (utime->now) \
4580 time = NULL; \
4581 else { \
4582 ts[0].tv_sec = utime->atime_s; \
4583 ts[0].tv_nsec = utime->atime_ns; \
4584 ts[1].tv_sec = utime->mtime_s; \
4585 ts[1].tv_nsec = utime->mtime_ns; \
4586 time = ts; \
4587 } \
4588
4589#define UTIME_TO_TIMEVAL \
4590 struct timeval tv[2]; \
4591 struct timeval *time; \
4592 if (utime->now) \
4593 time = NULL; \
4594 else { \
4595 tv[0].tv_sec = utime->atime_s; \
4596 tv[0].tv_usec = utime->atime_ns / 1000; \
4597 tv[1].tv_sec = utime->mtime_s; \
4598 tv[1].tv_usec = utime->mtime_ns / 1000; \
4599 time = tv; \
4600 } \
4601
4602#define UTIME_TO_UTIMBUF \
4603 struct utimbuf u[2]; \
4604 struct utimbuf *time; \
4605 if (utime->now) \
4606 time = NULL; \
4607 else { \
4608 u.actime = utime->atime_s; \
4609 u.modtime = utime->mtime_s; \
4610 time = u; \
4611 }
4612
4613#define UTIME_TO_TIME_T \
4614 time_t timet[2]; \
4615 struct timet time; \
4616 if (utime->now) \
4617 time = NULL; \
4618 else { \
4619 timet[0] = utime->atime_s; \
4620 timet[1] = utime->mtime_s; \
4621 time = &timet; \
4622 } \
4623
4624
4625#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4626
4627#if UTIME_HAVE_DIR_FD
4628
4629static int
4630utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks)
4631{
4632#ifdef HAVE_UTIMENSAT
4633 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4634 UTIME_TO_TIMESPEC;
4635 return utimensat(dir_fd, path, time, flags);
4636#elif defined(HAVE_FUTIMESAT)
4637 UTIME_TO_TIMEVAL;
4638 /*
4639 * follow_symlinks will never be false here;
4640 * we only allow !follow_symlinks and dir_fd together
4641 * if we have utimensat()
4642 */
4643 assert(follow_symlinks);
4644 return futimesat(dir_fd, path, time);
4645#endif
4646}
4647
4648#endif
4649
4650#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4651
4652#if UTIME_HAVE_FD
4653
4654static int
4655utime_fd(utime_t *utime, int fd)
4656{
4657#ifdef HAVE_FUTIMENS
4658 UTIME_TO_TIMESPEC;
4659 return futimens(fd, time);
4660#else
4661 UTIME_TO_TIMEVAL;
4662 return futimes(fd, time);
4663#endif
4664}
4665
4666#endif
4667
4668
4669#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4670 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4671
4672#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4673
4674static int
4675utime_nofollow_symlinks(utime_t *utime, char *path)
4676{
4677#ifdef HAVE_UTIMENSAT
4678 UTIME_TO_TIMESPEC;
4679 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4680#else
4681 UTIME_TO_TIMEVAL;
4682 return lutimes(path, time);
4683#endif
4684}
4685
4686#endif
4687
4688#ifndef MS_WINDOWS
4689
4690static int
4691utime_default(utime_t *utime, char *path)
4692{
4693#ifdef HAVE_UTIMENSAT
4694 UTIME_TO_TIMESPEC;
4695 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4696#elif defined(HAVE_UTIMES)
4697 UTIME_TO_TIMEVAL;
4698 return utimes(path, time);
4699#elif defined(HAVE_UTIME_H)
4700 UTIME_TO_UTIMBUF;
4701 return utime(path, time);
4702#else
4703 UTIME_TO_TIME_T;
4704 return utime(path, time);
4705#endif
4706}
4707
4708#endif
4709
Larry Hastings76ad59b2012-05-03 00:30:07 -07004710static int
4711split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4712{
4713 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004714 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004715 divmod = PyNumber_Divmod(py_long, billion);
4716 if (!divmod)
4717 goto exit;
4718 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4719 if ((*s == -1) && PyErr_Occurred())
4720 goto exit;
4721 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004722 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004723 goto exit;
4724
4725 result = 1;
4726exit:
4727 Py_XDECREF(divmod);
4728 return result;
4729}
4730
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731static PyObject *
4732posix_utime(PyObject *self, PyObject *args, PyObject *kwargs)
Larry Hastings76ad59b2012-05-03 00:30:07 -07004733{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 path_t path;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004735 PyObject *times = NULL;
4736 PyObject *ns = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737 int dir_fd = DEFAULT_DIR_FD;
4738 int follow_symlinks = 1;
4739 char *keywords[] = {"path", "times", "ns", "dir_fd",
4740 "follow_symlinks", NULL};
Larry Hastings76ad59b2012-05-03 00:30:07 -07004741
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004743
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744#ifdef MS_WINDOWS
4745 HANDLE hFile;
4746 FILETIME atime, mtime;
4747#else
4748 int result;
4749#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004750
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 PyObject *return_value = NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004752
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 memset(&path, 0, sizeof(path));
4754#if UTIME_HAVE_FD
4755 path.allow_fd = 1;
4756#endif
4757 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
4758 "O&|O$OO&p:utime", keywords,
4759 path_converter, &path,
4760 &times, &ns,
4761#if UTIME_HAVE_DIR_FD
4762 dir_fd_converter, &dir_fd,
4763#else
4764 dir_fd_unavailable, &dir_fd,
4765#endif
4766 &follow_symlinks
4767 ))
4768 return NULL;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004769
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 if (times && (times != Py_None) && ns) {
4771 PyErr_SetString(PyExc_ValueError,
4772 "utime: you may specify either 'times'"
4773 " or 'ns' but not both");
4774 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004775 }
4776
4777 if (times && (times != Py_None)) {
4778 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779 PyErr_SetString(PyExc_TypeError,
4780 "utime: 'times' must be either"
4781 " a tuple of two ints or None");
4782 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004783 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004785 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004786 &utime.atime_s, &utime.atime_ns) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004787 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004788 &utime.mtime_s, &utime.mtime_ns) == -1) {
4789 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004790 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004791 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004793 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 PyErr_SetString(PyExc_TypeError,
4795 "utime: 'ns' must be a tuple of two ints");
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 (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004800 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004801 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004802 &utime.mtime_s, &utime.mtime_ns)) {
4803 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004804 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004805 }
4806 else {
4807 /* times and ns are both None/unspecified. use "now". */
4808 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004809 }
4810
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4812 if (follow_symlinks_specified("utime", follow_symlinks))
4813 goto exit;
4814#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004815
Larry Hastings9cf065c2012-06-22 16:30:09 -07004816 if (path_and_dir_fd_invalid("utime", &path, dir_fd) ||
4817 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) ||
4818 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks))
4819 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004820
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821#if !defined(HAVE_UTIMENSAT)
4822 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004823 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004824 "utime: cannot use dir_fd and follow_symlinks "
4825 "together on this platform");
4826 goto exit;
4827 }
4828#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004829
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004830#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831 Py_BEGIN_ALLOW_THREADS
4832 if (path.wide)
4833 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 NULL, OPEN_EXISTING,
4835 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004836 else
4837 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 NULL, OPEN_EXISTING,
4839 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840 Py_END_ALLOW_THREADS
4841 if (hFile == INVALID_HANDLE_VALUE) {
4842 win32_error_object("utime", path.object);
4843 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004844 }
4845
Larry Hastings9cf065c2012-06-22 16:30:09 -07004846 if (utime.now) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 SYSTEMTIME now;
4848 GetSystemTime(&now);
4849 if (!SystemTimeToFileTime(&now, &mtime) ||
4850 !SystemTimeToFileTime(&now, &atime)) {
4851 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852 goto exit;
Stefan Krah0e803b32010-11-26 16:16:47 +00004853 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004854 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004856 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4857 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004858 }
4859 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4860 /* Avoid putting the file name into the error here,
4861 as that may confuse the user into believing that
4862 something is wrong with the file, when it also
4863 could be the time stamp that gives a problem. */
4864 win32_error("utime", NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004865 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004866 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004867#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004868 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004869
Larry Hastings9cf065c2012-06-22 16:30:09 -07004870#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4871 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
4872 result = utime_nofollow_symlinks(&utime, path.narrow);
4873 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004874#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004875
4876#if UTIME_HAVE_DIR_FD
4877 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
4878 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks);
4879 else
4880#endif
4881
4882#if UTIME_HAVE_FD
4883 if (path.fd != -1)
4884 result = utime_fd(&utime, path.fd);
4885 else
4886#endif
4887
4888 result = utime_default(&utime, path.narrow);
4889
4890 Py_END_ALLOW_THREADS
4891
4892 if (result < 0) {
4893 /* see previous comment about not putting filename in error here */
4894 return_value = posix_error();
4895 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004896 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004897
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004898#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004899
4900 Py_INCREF(Py_None);
4901 return_value = Py_None;
4902
4903exit:
4904 path_cleanup(&path);
4905#ifdef MS_WINDOWS
4906 if (hFile != INVALID_HANDLE_VALUE)
4907 CloseHandle(hFile);
4908#endif
4909 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004910}
4911
Guido van Rossum3b066191991-06-04 19:40:25 +00004912/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004914PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004915"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004917
Barry Warsaw53699e91996-12-10 23:23:01 +00004918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004919posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004920{
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 int sts;
4922 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
4923 return NULL;
4924 _exit(sts);
4925 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004926}
4927
Martin v. Löwis114619e2002-10-07 06:44:21 +00004928#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4929static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004930free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004931{
Victor Stinner8c62be82010-05-06 00:08:46 +00004932 Py_ssize_t i;
4933 for (i = 0; i < count; i++)
4934 PyMem_Free(array[i]);
4935 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004936}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004937
Antoine Pitrou69f71142009-05-24 21:25:49 +00004938static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004939int fsconvert_strdup(PyObject *o, char**out)
4940{
Victor Stinner8c62be82010-05-06 00:08:46 +00004941 PyObject *bytes;
4942 Py_ssize_t size;
4943 if (!PyUnicode_FSConverter(o, &bytes))
4944 return 0;
4945 size = PyBytes_GET_SIZE(bytes);
4946 *out = PyMem_Malloc(size+1);
4947 if (!*out)
4948 return 0;
4949 memcpy(*out, PyBytes_AsString(bytes), size+1);
4950 Py_DECREF(bytes);
4951 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004952}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004953#endif
4954
Ross Lagerwall7807c352011-03-17 20:20:30 +02004955#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004956static char**
4957parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4958{
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 char **envlist;
4960 Py_ssize_t i, pos, envc;
4961 PyObject *keys=NULL, *vals=NULL;
4962 PyObject *key, *val, *key2, *val2;
4963 char *p, *k, *v;
4964 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004965
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 i = PyMapping_Size(env);
4967 if (i < 0)
4968 return NULL;
4969 envlist = PyMem_NEW(char *, i + 1);
4970 if (envlist == NULL) {
4971 PyErr_NoMemory();
4972 return NULL;
4973 }
4974 envc = 0;
4975 keys = PyMapping_Keys(env);
4976 vals = PyMapping_Values(env);
4977 if (!keys || !vals)
4978 goto error;
4979 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4980 PyErr_Format(PyExc_TypeError,
4981 "env.keys() or env.values() is not a list");
4982 goto error;
4983 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004984
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 for (pos = 0; pos < i; pos++) {
4986 key = PyList_GetItem(keys, pos);
4987 val = PyList_GetItem(vals, pos);
4988 if (!key || !val)
4989 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004990
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 if (PyUnicode_FSConverter(key, &key2) == 0)
4992 goto error;
4993 if (PyUnicode_FSConverter(val, &val2) == 0) {
4994 Py_DECREF(key2);
4995 goto error;
4996 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004997
4998#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
5000 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00005001#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 k = PyBytes_AsString(key2);
5003 v = PyBytes_AsString(val2);
5004 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005005
Victor Stinner8c62be82010-05-06 00:08:46 +00005006 p = PyMem_NEW(char, len);
5007 if (p == NULL) {
5008 PyErr_NoMemory();
5009 Py_DECREF(key2);
5010 Py_DECREF(val2);
5011 goto error;
5012 }
5013 PyOS_snprintf(p, len, "%s=%s", k, v);
5014 envlist[envc++] = p;
5015 Py_DECREF(key2);
5016 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005017#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00005018 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005019#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 }
5021 Py_DECREF(vals);
5022 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005023
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 envlist[envc] = 0;
5025 *envc_ptr = envc;
5026 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005027
5028error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005029 Py_XDECREF(keys);
5030 Py_XDECREF(vals);
5031 while (--envc >= 0)
5032 PyMem_DEL(envlist[envc]);
5033 PyMem_DEL(envlist);
5034 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005035}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005036
Ross Lagerwall7807c352011-03-17 20:20:30 +02005037static char**
5038parse_arglist(PyObject* argv, Py_ssize_t *argc)
5039{
5040 int i;
5041 char **argvlist = PyMem_NEW(char *, *argc+1);
5042 if (argvlist == NULL) {
5043 PyErr_NoMemory();
5044 return NULL;
5045 }
5046 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005047 PyObject* item = PySequence_ITEM(argv, i);
5048 if (item == NULL)
5049 goto fail;
5050 if (!fsconvert_strdup(item, &argvlist[i])) {
5051 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005052 goto fail;
5053 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005054 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005055 }
5056 argvlist[*argc] = NULL;
5057 return argvlist;
5058fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005059 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005060 free_string_array(argvlist, *argc);
5061 return NULL;
5062}
5063#endif
5064
5065#ifdef HAVE_EXECV
5066PyDoc_STRVAR(posix_execv__doc__,
5067"execv(path, args)\n\n\
5068Execute an executable path with arguments, replacing current process.\n\
5069\n\
5070 path: path of executable file\n\
5071 args: tuple or list of strings");
5072
5073static PyObject *
5074posix_execv(PyObject *self, PyObject *args)
5075{
5076 PyObject *opath;
5077 char *path;
5078 PyObject *argv;
5079 char **argvlist;
5080 Py_ssize_t argc;
5081
5082 /* execv has two arguments: (path, argv), where
5083 argv is a list or tuple of strings. */
5084
5085 if (!PyArg_ParseTuple(args, "O&O:execv",
5086 PyUnicode_FSConverter,
5087 &opath, &argv))
5088 return NULL;
5089 path = PyBytes_AsString(opath);
5090 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5091 PyErr_SetString(PyExc_TypeError,
5092 "execv() arg 2 must be a tuple or list");
5093 Py_DECREF(opath);
5094 return NULL;
5095 }
5096 argc = PySequence_Size(argv);
5097 if (argc < 1) {
5098 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
5099 Py_DECREF(opath);
5100 return NULL;
5101 }
5102
5103 argvlist = parse_arglist(argv, &argc);
5104 if (argvlist == NULL) {
5105 Py_DECREF(opath);
5106 return NULL;
5107 }
5108
5109 execv(path, argvlist);
5110
5111 /* If we get here it's definitely an error */
5112
5113 free_string_array(argvlist, argc);
5114 Py_DECREF(opath);
5115 return posix_error();
5116}
5117
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005118PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005119"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005120Execute a path with arguments and environment, replacing current process.\n\
5121\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 path: path of executable file\n\
5123 args: tuple or list of arguments\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124 env: dictionary of strings mapping to strings\n\
5125\n\
5126On some platforms, you may specify an open file descriptor for path;\n\
5127 execve will execute the program the file descriptor is open to.\n\
5128 If this functionality is unavailable, using it raises NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005129
Barry Warsaw53699e91996-12-10 23:23:01 +00005130static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07005131posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005132{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005133 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 PyObject *argv, *env;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005135 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005136 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005137 Py_ssize_t argc, envc;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005138 static char *keywords[] = {"path", "argv", "environment", NULL};
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005139
Victor Stinner8c62be82010-05-06 00:08:46 +00005140 /* execve has three arguments: (path, argv, env), where
5141 argv is a list or tuple of strings and env is a dictionary
5142 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005143
Larry Hastings9cf065c2012-06-22 16:30:09 -07005144 memset(&path, 0, sizeof(path));
5145#ifdef HAVE_FEXECVE
5146 path.allow_fd = 1;
5147#endif
5148 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords,
5149 path_converter, &path,
5150 &argv, &env
5151 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07005153
Ross Lagerwall7807c352011-03-17 20:20:30 +02005154 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156 "execve: argv must be a tuple or list");
5157 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005159 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005160 if (!PyMapping_Check(env)) {
5161 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005162 "execve: environment must be a mapping object");
5163 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005165
Ross Lagerwall7807c352011-03-17 20:20:30 +02005166 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005167 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005168 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005170
Victor Stinner8c62be82010-05-06 00:08:46 +00005171 envlist = parse_envlist(env, &envc);
5172 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005173 goto fail;
5174
Larry Hastings9cf065c2012-06-22 16:30:09 -07005175#ifdef HAVE_FEXECVE
5176 if (path.fd > -1)
5177 fexecve(path.fd, argvlist, envlist);
5178 else
5179#endif
5180 execve(path.narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005181
5182 /* If we get here it's definitely an error */
5183
Larry Hastings9cf065c2012-06-22 16:30:09 -07005184 path_posix_error("execve", &path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005185
5186 while (--envc >= 0)
5187 PyMem_DEL(envlist[envc]);
5188 PyMem_DEL(envlist);
5189 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005190 if (argvlist)
5191 free_string_array(argvlist, argc);
5192 path_cleanup(&path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005193 return NULL;
5194}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005195#endif /* HAVE_EXECV */
5196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005197
Guido van Rossuma1065681999-01-25 23:20:23 +00005198#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005199PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005200"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005201Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005202\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 mode: mode of process creation\n\
5204 path: path of executable file\n\
5205 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005206
5207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005208posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005209{
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 PyObject *opath;
5211 char *path;
5212 PyObject *argv;
5213 char **argvlist;
5214 int mode, i;
5215 Py_ssize_t argc;
5216 Py_intptr_t spawnval;
5217 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005218
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 /* spawnv has three arguments: (mode, path, argv), where
5220 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005221
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
5223 PyUnicode_FSConverter,
5224 &opath, &argv))
5225 return NULL;
5226 path = PyBytes_AsString(opath);
5227 if (PyList_Check(argv)) {
5228 argc = PyList_Size(argv);
5229 getitem = PyList_GetItem;
5230 }
5231 else if (PyTuple_Check(argv)) {
5232 argc = PyTuple_Size(argv);
5233 getitem = PyTuple_GetItem;
5234 }
5235 else {
5236 PyErr_SetString(PyExc_TypeError,
5237 "spawnv() arg 2 must be a tuple or list");
5238 Py_DECREF(opath);
5239 return NULL;
5240 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005241
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 argvlist = PyMem_NEW(char *, argc+1);
5243 if (argvlist == NULL) {
5244 Py_DECREF(opath);
5245 return PyErr_NoMemory();
5246 }
5247 for (i = 0; i < argc; i++) {
5248 if (!fsconvert_strdup((*getitem)(argv, i),
5249 &argvlist[i])) {
5250 free_string_array(argvlist, i);
5251 PyErr_SetString(
5252 PyExc_TypeError,
5253 "spawnv() arg 2 must contain only strings");
5254 Py_DECREF(opath);
5255 return NULL;
5256 }
5257 }
5258 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005259
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005260#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 Py_BEGIN_ALLOW_THREADS
5262 spawnval = spawnv(mode, path, argvlist);
5263 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005264#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 if (mode == _OLD_P_OVERLAY)
5266 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005267
Victor Stinner8c62be82010-05-06 00:08:46 +00005268 Py_BEGIN_ALLOW_THREADS
5269 spawnval = _spawnv(mode, path, argvlist);
5270 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005271#endif
Tim Peters5aa91602002-01-30 05:46:57 +00005272
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 free_string_array(argvlist, argc);
5274 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00005275
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 if (spawnval == -1)
5277 return posix_error();
5278 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005279#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005280 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005281#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005282 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005283#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005284}
5285
5286
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005287PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005288"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00005289Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00005290\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 mode: mode of process creation\n\
5292 path: path of executable file\n\
5293 args: tuple or list of arguments\n\
5294 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00005295
5296static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005297posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00005298{
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 PyObject *opath;
5300 char *path;
5301 PyObject *argv, *env;
5302 char **argvlist;
5303 char **envlist;
5304 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005305 int mode;
5306 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 Py_intptr_t spawnval;
5308 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5309 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005310
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 /* spawnve has four arguments: (mode, path, argv, env), where
5312 argv is a list or tuple of strings and env is a dictionary
5313 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005314
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
5316 PyUnicode_FSConverter,
5317 &opath, &argv, &env))
5318 return NULL;
5319 path = PyBytes_AsString(opath);
5320 if (PyList_Check(argv)) {
5321 argc = PyList_Size(argv);
5322 getitem = PyList_GetItem;
5323 }
5324 else if (PyTuple_Check(argv)) {
5325 argc = PyTuple_Size(argv);
5326 getitem = PyTuple_GetItem;
5327 }
5328 else {
5329 PyErr_SetString(PyExc_TypeError,
5330 "spawnve() arg 2 must be a tuple or list");
5331 goto fail_0;
5332 }
5333 if (!PyMapping_Check(env)) {
5334 PyErr_SetString(PyExc_TypeError,
5335 "spawnve() arg 3 must be a mapping object");
5336 goto fail_0;
5337 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005338
Victor Stinner8c62be82010-05-06 00:08:46 +00005339 argvlist = PyMem_NEW(char *, argc+1);
5340 if (argvlist == NULL) {
5341 PyErr_NoMemory();
5342 goto fail_0;
5343 }
5344 for (i = 0; i < argc; i++) {
5345 if (!fsconvert_strdup((*getitem)(argv, i),
5346 &argvlist[i]))
5347 {
5348 lastarg = i;
5349 goto fail_1;
5350 }
5351 }
5352 lastarg = argc;
5353 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005354
Victor Stinner8c62be82010-05-06 00:08:46 +00005355 envlist = parse_envlist(env, &envc);
5356 if (envlist == NULL)
5357 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005358
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005359#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005360 Py_BEGIN_ALLOW_THREADS
5361 spawnval = spawnve(mode, path, argvlist, envlist);
5362 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005363#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005364 if (mode == _OLD_P_OVERLAY)
5365 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005366
Victor Stinner8c62be82010-05-06 00:08:46 +00005367 Py_BEGIN_ALLOW_THREADS
5368 spawnval = _spawnve(mode, path, argvlist, envlist);
5369 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005370#endif
Tim Peters25059d32001-12-07 20:35:43 +00005371
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 if (spawnval == -1)
5373 (void) posix_error();
5374 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00005375#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00005376 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005377#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00005379#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005380
Victor Stinner8c62be82010-05-06 00:08:46 +00005381 while (--envc >= 0)
5382 PyMem_DEL(envlist[envc]);
5383 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005384 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005386 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005387 Py_DECREF(opath);
5388 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005389}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005390
5391/* OS/2 supports spawnvp & spawnvpe natively */
5392#if defined(PYOS_OS2)
5393PyDoc_STRVAR(posix_spawnvp__doc__,
5394"spawnvp(mode, file, args)\n\n\
5395Execute the program 'file' in a new process, using the environment\n\
5396search path to find the file.\n\
5397\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 mode: mode of process creation\n\
5399 file: executable file name\n\
5400 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005401
5402static PyObject *
5403posix_spawnvp(PyObject *self, PyObject *args)
5404{
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 PyObject *opath;
5406 char *path;
5407 PyObject *argv;
5408 char **argvlist;
5409 int mode, i, argc;
5410 Py_intptr_t spawnval;
5411 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005412
Victor Stinner8c62be82010-05-06 00:08:46 +00005413 /* spawnvp has three arguments: (mode, path, argv), where
5414 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005415
Victor Stinner8c62be82010-05-06 00:08:46 +00005416 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
5417 PyUnicode_FSConverter,
5418 &opath, &argv))
5419 return NULL;
5420 path = PyBytes_AsString(opath);
5421 if (PyList_Check(argv)) {
5422 argc = PyList_Size(argv);
5423 getitem = PyList_GetItem;
5424 }
5425 else if (PyTuple_Check(argv)) {
5426 argc = PyTuple_Size(argv);
5427 getitem = PyTuple_GetItem;
5428 }
5429 else {
5430 PyErr_SetString(PyExc_TypeError,
5431 "spawnvp() arg 2 must be a tuple or list");
5432 Py_DECREF(opath);
5433 return NULL;
5434 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005435
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 argvlist = PyMem_NEW(char *, argc+1);
5437 if (argvlist == NULL) {
5438 Py_DECREF(opath);
5439 return PyErr_NoMemory();
5440 }
5441 for (i = 0; i < argc; i++) {
5442 if (!fsconvert_strdup((*getitem)(argv, i),
5443 &argvlist[i])) {
5444 free_string_array(argvlist, i);
5445 PyErr_SetString(
5446 PyExc_TypeError,
5447 "spawnvp() arg 2 must contain only strings");
5448 Py_DECREF(opath);
5449 return NULL;
5450 }
5451 }
5452 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005453
Victor Stinner8c62be82010-05-06 00:08:46 +00005454 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005455#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005456 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005457#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005458 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005459#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005460 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005461
Victor Stinner8c62be82010-05-06 00:08:46 +00005462 free_string_array(argvlist, argc);
5463 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005464
Victor Stinner8c62be82010-05-06 00:08:46 +00005465 if (spawnval == -1)
5466 return posix_error();
5467 else
5468 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005469}
5470
5471
5472PyDoc_STRVAR(posix_spawnvpe__doc__,
5473"spawnvpe(mode, file, args, env)\n\n\
5474Execute the program 'file' in a new process, using the environment\n\
5475search path to find the file.\n\
5476\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00005477 mode: mode of process creation\n\
5478 file: executable file name\n\
5479 args: tuple or list of arguments\n\
5480 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005481
5482static PyObject *
5483posix_spawnvpe(PyObject *self, PyObject *args)
5484{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02005485 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005486 char *path;
5487 PyObject *argv, *env;
5488 char **argvlist;
5489 char **envlist;
5490 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005491 int mode;
5492 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005493 Py_intptr_t spawnval;
5494 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5495 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005496
Victor Stinner8c62be82010-05-06 00:08:46 +00005497 /* spawnvpe has four arguments: (mode, path, argv, env), where
5498 argv is a list or tuple of strings and env is a dictionary
5499 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005500
Victor Stinner8c62be82010-05-06 00:08:46 +00005501 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
5502 PyUnicode_FSConverter,
5503 &opath, &argv, &env))
5504 return NULL;
5505 path = PyBytes_AsString(opath);
5506 if (PyList_Check(argv)) {
5507 argc = PyList_Size(argv);
5508 getitem = PyList_GetItem;
5509 }
5510 else if (PyTuple_Check(argv)) {
5511 argc = PyTuple_Size(argv);
5512 getitem = PyTuple_GetItem;
5513 }
5514 else {
5515 PyErr_SetString(PyExc_TypeError,
5516 "spawnvpe() arg 2 must be a tuple or list");
5517 goto fail_0;
5518 }
5519 if (!PyMapping_Check(env)) {
5520 PyErr_SetString(PyExc_TypeError,
5521 "spawnvpe() arg 3 must be a mapping object");
5522 goto fail_0;
5523 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005524
Victor Stinner8c62be82010-05-06 00:08:46 +00005525 argvlist = PyMem_NEW(char *, argc+1);
5526 if (argvlist == NULL) {
5527 PyErr_NoMemory();
5528 goto fail_0;
5529 }
5530 for (i = 0; i < argc; i++) {
5531 if (!fsconvert_strdup((*getitem)(argv, i),
5532 &argvlist[i]))
5533 {
5534 lastarg = i;
5535 goto fail_1;
5536 }
5537 }
5538 lastarg = argc;
5539 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005540
Victor Stinner8c62be82010-05-06 00:08:46 +00005541 envlist = parse_envlist(env, &envc);
5542 if (envlist == NULL)
5543 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005544
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005546#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005547 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005548#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005549 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005550#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005552
Victor Stinner8c62be82010-05-06 00:08:46 +00005553 if (spawnval == -1)
5554 (void) posix_error();
5555 else
5556 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005557
Victor Stinner8c62be82010-05-06 00:08:46 +00005558 while (--envc >= 0)
5559 PyMem_DEL(envlist[envc]);
5560 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005561 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005562 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005563 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005564 Py_DECREF(opath);
5565 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005566}
5567#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00005568#endif /* HAVE_SPAWNV */
5569
5570
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005571#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005572PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005573"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005574Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
5575\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005577
5578static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005579posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005580{
Victor Stinner8c62be82010-05-06 00:08:46 +00005581 pid_t pid;
5582 int result = 0;
5583 _PyImport_AcquireLock();
5584 pid = fork1();
5585 if (pid == 0) {
5586 /* child: this clobbers and resets the import lock. */
5587 PyOS_AfterFork();
5588 } else {
5589 /* parent: release the import lock. */
5590 result = _PyImport_ReleaseLock();
5591 }
5592 if (pid == -1)
5593 return posix_error();
5594 if (result < 0) {
5595 /* Don't clobber the OSError if the fork failed. */
5596 PyErr_SetString(PyExc_RuntimeError,
5597 "not holding the import lock");
5598 return NULL;
5599 }
5600 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005601}
5602#endif
5603
5604
Guido van Rossumad0ee831995-03-01 10:34:45 +00005605#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005607"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005608Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005609Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005610
Barry Warsaw53699e91996-12-10 23:23:01 +00005611static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005612posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005613{
Victor Stinner8c62be82010-05-06 00:08:46 +00005614 pid_t pid;
5615 int result = 0;
5616 _PyImport_AcquireLock();
5617 pid = fork();
5618 if (pid == 0) {
5619 /* child: this clobbers and resets the import lock. */
5620 PyOS_AfterFork();
5621 } else {
5622 /* parent: release the import lock. */
5623 result = _PyImport_ReleaseLock();
5624 }
5625 if (pid == -1)
5626 return posix_error();
5627 if (result < 0) {
5628 /* Don't clobber the OSError if the fork failed. */
5629 PyErr_SetString(PyExc_RuntimeError,
5630 "not holding the import lock");
5631 return NULL;
5632 }
5633 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005634}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005635#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005636
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005637#ifdef HAVE_SCHED_H
5638
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005639#ifdef HAVE_SCHED_GET_PRIORITY_MAX
5640
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005641PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
5642"sched_get_priority_max(policy)\n\n\
5643Get the maximum scheduling priority for *policy*.");
5644
5645static PyObject *
5646posix_sched_get_priority_max(PyObject *self, PyObject *args)
5647{
5648 int policy, max;
5649
5650 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
5651 return NULL;
5652 max = sched_get_priority_max(policy);
5653 if (max < 0)
5654 return posix_error();
5655 return PyLong_FromLong(max);
5656}
5657
5658PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
5659"sched_get_priority_min(policy)\n\n\
5660Get the minimum scheduling priority for *policy*.");
5661
5662static PyObject *
5663posix_sched_get_priority_min(PyObject *self, PyObject *args)
5664{
5665 int policy, min;
5666
5667 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
5668 return NULL;
5669 min = sched_get_priority_min(policy);
5670 if (min < 0)
5671 return posix_error();
5672 return PyLong_FromLong(min);
5673}
5674
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005675#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5676
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005677#ifdef HAVE_SCHED_SETSCHEDULER
5678
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005679PyDoc_STRVAR(posix_sched_getscheduler__doc__,
5680"sched_getscheduler(pid)\n\n\
5681Get the scheduling policy for the process with a PID of *pid*.\n\
5682Passing a PID of 0 returns the scheduling policy for the calling process.");
5683
5684static PyObject *
5685posix_sched_getscheduler(PyObject *self, PyObject *args)
5686{
5687 pid_t pid;
5688 int policy;
5689
5690 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
5691 return NULL;
5692 policy = sched_getscheduler(pid);
5693 if (policy < 0)
5694 return posix_error();
5695 return PyLong_FromLong(policy);
5696}
5697
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005698#endif
5699
5700#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
5701
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005702static PyObject *
5703sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
5704{
5705 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05005706 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005707
5708 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
5709 return NULL;
5710 res = PyStructSequence_New(type);
5711 if (!res)
5712 return NULL;
5713 Py_INCREF(priority);
5714 PyStructSequence_SET_ITEM(res, 0, priority);
5715 return res;
5716}
5717
5718PyDoc_STRVAR(sched_param__doc__,
5719"sched_param(sched_priority): A scheduling parameter.\n\n\
5720Current has only one field: sched_priority");
5721
5722static PyStructSequence_Field sched_param_fields[] = {
5723 {"sched_priority", "the scheduling priority"},
5724 {0}
5725};
5726
5727static PyStructSequence_Desc sched_param_desc = {
5728 "sched_param", /* name */
5729 sched_param__doc__, /* doc */
5730 sched_param_fields,
5731 1
5732};
5733
5734static int
5735convert_sched_param(PyObject *param, struct sched_param *res)
5736{
5737 long priority;
5738
5739 if (Py_TYPE(param) != &SchedParamType) {
5740 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5741 return 0;
5742 }
5743 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5744 if (priority == -1 && PyErr_Occurred())
5745 return 0;
5746 if (priority > INT_MAX || priority < INT_MIN) {
5747 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5748 return 0;
5749 }
5750 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5751 return 1;
5752}
5753
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005754#endif
5755
5756#ifdef HAVE_SCHED_SETSCHEDULER
5757
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005758PyDoc_STRVAR(posix_sched_setscheduler__doc__,
5759"sched_setscheduler(pid, policy, param)\n\n\
5760Set the scheduling policy, *policy*, for *pid*.\n\
5761If *pid* is 0, the calling process is changed.\n\
5762*param* is an instance of sched_param.");
5763
5764static PyObject *
5765posix_sched_setscheduler(PyObject *self, PyObject *args)
5766{
5767 pid_t pid;
5768 int policy;
5769 struct sched_param param;
5770
5771 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
5772 &pid, &policy, &convert_sched_param, &param))
5773 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02005774
5775 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005776 ** sched_setscheduler() returns 0 in Linux, but the previous
5777 ** scheduling policy under Solaris/Illumos, and others.
5778 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005779 */
5780 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005781 return posix_error();
5782 Py_RETURN_NONE;
5783}
5784
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005785#endif
5786
5787#ifdef HAVE_SCHED_SETPARAM
5788
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005789PyDoc_STRVAR(posix_sched_getparam__doc__,
5790"sched_getparam(pid) -> sched_param\n\n\
5791Returns scheduling parameters for the process with *pid* as an instance of the\n\
5792sched_param class. A PID of 0 means the calling process.");
5793
5794static PyObject *
5795posix_sched_getparam(PyObject *self, PyObject *args)
5796{
5797 pid_t pid;
5798 struct sched_param param;
5799 PyObject *res, *priority;
5800
5801 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
5802 return NULL;
5803 if (sched_getparam(pid, &param))
5804 return posix_error();
5805 res = PyStructSequence_New(&SchedParamType);
5806 if (!res)
5807 return NULL;
5808 priority = PyLong_FromLong(param.sched_priority);
5809 if (!priority) {
5810 Py_DECREF(res);
5811 return NULL;
5812 }
5813 PyStructSequence_SET_ITEM(res, 0, priority);
5814 return res;
5815}
5816
5817PyDoc_STRVAR(posix_sched_setparam__doc__,
5818"sched_setparam(pid, param)\n\n\
5819Set scheduling parameters for a process with PID *pid*.\n\
5820A PID of 0 means the calling process.");
5821
5822static PyObject *
5823posix_sched_setparam(PyObject *self, PyObject *args)
5824{
5825 pid_t pid;
5826 struct sched_param param;
5827
5828 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
5829 &pid, &convert_sched_param, &param))
5830 return NULL;
5831 if (sched_setparam(pid, &param))
5832 return posix_error();
5833 Py_RETURN_NONE;
5834}
5835
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005836#endif
5837
5838#ifdef HAVE_SCHED_RR_GET_INTERVAL
5839
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005840PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
5841"sched_rr_get_interval(pid) -> float\n\n\
5842Return the round-robin quantum for the process with PID *pid* in seconds.");
5843
5844static PyObject *
5845posix_sched_rr_get_interval(PyObject *self, PyObject *args)
5846{
5847 pid_t pid;
5848 struct timespec interval;
5849
5850 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
5851 return NULL;
5852 if (sched_rr_get_interval(pid, &interval))
5853 return posix_error();
5854 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
5855}
5856
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005857#endif
5858
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005859PyDoc_STRVAR(posix_sched_yield__doc__,
5860"sched_yield()\n\n\
5861Voluntarily relinquish the CPU.");
5862
5863static PyObject *
5864posix_sched_yield(PyObject *self, PyObject *noargs)
5865{
5866 if (sched_yield())
5867 return posix_error();
5868 Py_RETURN_NONE;
5869}
5870
Benjamin Peterson2740af82011-08-02 17:41:34 -05005871#ifdef HAVE_SCHED_SETAFFINITY
5872
Antoine Pitrou84869872012-08-04 16:16:35 +02005873/* The minimum number of CPUs allocated in a cpu_set_t */
5874static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005875
5876PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5877"sched_setaffinity(pid, cpu_set)\n\n\
5878Set the affinity of the process with PID *pid* to *cpu_set*.");
5879
5880static PyObject *
5881posix_sched_setaffinity(PyObject *self, PyObject *args)
5882{
5883 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005884 int ncpus;
5885 size_t setsize;
5886 cpu_set_t *mask = NULL;
5887 PyObject *iterable, *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005888
Antoine Pitrou84869872012-08-04 16:16:35 +02005889 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity",
5890 &pid, &iterable))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005891 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005892
5893 iterator = PyObject_GetIter(iterable);
5894 if (iterator == NULL)
5895 return NULL;
5896
5897 ncpus = NCPUS_START;
5898 setsize = CPU_ALLOC_SIZE(ncpus);
5899 mask = CPU_ALLOC(ncpus);
5900 if (mask == NULL) {
5901 PyErr_NoMemory();
5902 goto error;
5903 }
5904 CPU_ZERO_S(setsize, mask);
5905
5906 while ((item = PyIter_Next(iterator))) {
5907 long cpu;
5908 if (!PyLong_Check(item)) {
5909 PyErr_Format(PyExc_TypeError,
5910 "expected an iterator of ints, "
5911 "but iterator yielded %R",
5912 Py_TYPE(item));
5913 Py_DECREF(item);
5914 goto error;
5915 }
5916 cpu = PyLong_AsLong(item);
5917 Py_DECREF(item);
5918 if (cpu < 0) {
5919 if (!PyErr_Occurred())
5920 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5921 goto error;
5922 }
5923 if (cpu > INT_MAX - 1) {
5924 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5925 goto error;
5926 }
5927 if (cpu >= ncpus) {
5928 /* Grow CPU mask to fit the CPU number */
5929 int newncpus = ncpus;
5930 cpu_set_t *newmask;
5931 size_t newsetsize;
5932 while (newncpus <= cpu) {
5933 if (newncpus > INT_MAX / 2)
5934 newncpus = cpu + 1;
5935 else
5936 newncpus = newncpus * 2;
5937 }
5938 newmask = CPU_ALLOC(newncpus);
5939 if (newmask == NULL) {
5940 PyErr_NoMemory();
5941 goto error;
5942 }
5943 newsetsize = CPU_ALLOC_SIZE(newncpus);
5944 CPU_ZERO_S(newsetsize, newmask);
5945 memcpy(newmask, mask, setsize);
5946 CPU_FREE(mask);
5947 setsize = newsetsize;
5948 mask = newmask;
5949 ncpus = newncpus;
5950 }
5951 CPU_SET_S(cpu, setsize, mask);
5952 }
5953 Py_CLEAR(iterator);
5954
5955 if (sched_setaffinity(pid, setsize, mask)) {
5956 posix_error();
5957 goto error;
5958 }
5959 CPU_FREE(mask);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005960 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005961
5962error:
5963 if (mask)
5964 CPU_FREE(mask);
5965 Py_XDECREF(iterator);
5966 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005967}
5968
5969PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5970"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5971Return the affinity of the process with PID *pid*.\n\
5972The returned cpu_set will be of size *ncpus*.");
5973
5974static PyObject *
5975posix_sched_getaffinity(PyObject *self, PyObject *args)
5976{
5977 pid_t pid;
Antoine Pitrou84869872012-08-04 16:16:35 +02005978 int cpu, ncpus, count;
5979 size_t setsize;
5980 cpu_set_t *mask = NULL;
5981 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005982
Antoine Pitrou84869872012-08-04 16:16:35 +02005983 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity",
5984 &pid))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005985 return NULL;
Antoine Pitrou84869872012-08-04 16:16:35 +02005986
5987 ncpus = NCPUS_START;
5988 while (1) {
5989 setsize = CPU_ALLOC_SIZE(ncpus);
5990 mask = CPU_ALLOC(ncpus);
5991 if (mask == NULL)
5992 return PyErr_NoMemory();
5993 if (sched_getaffinity(pid, setsize, mask) == 0)
5994 break;
5995 CPU_FREE(mask);
5996 if (errno != EINVAL)
5997 return posix_error();
5998 if (ncpus > INT_MAX / 2) {
5999 PyErr_SetString(PyExc_OverflowError, "could not allocate "
6000 "a large enough CPU set");
6001 return NULL;
6002 }
6003 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006004 }
Antoine Pitrou84869872012-08-04 16:16:35 +02006005
6006 res = PySet_New(NULL);
6007 if (res == NULL)
6008 goto error;
6009 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
6010 if (CPU_ISSET_S(cpu, setsize, mask)) {
6011 PyObject *cpu_num = PyLong_FromLong(cpu);
6012 --count;
6013 if (cpu_num == NULL)
6014 goto error;
6015 if (PySet_Add(res, cpu_num)) {
6016 Py_DECREF(cpu_num);
6017 goto error;
6018 }
6019 Py_DECREF(cpu_num);
6020 }
6021 }
6022 CPU_FREE(mask);
6023 return res;
6024
6025error:
6026 if (mask)
6027 CPU_FREE(mask);
6028 Py_XDECREF(res);
6029 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006030}
6031
Benjamin Peterson2740af82011-08-02 17:41:34 -05006032#endif /* HAVE_SCHED_SETAFFINITY */
6033
Benjamin Peterson94b580d2011-08-02 17:30:04 -05006034#endif /* HAVE_SCHED_H */
6035
Neal Norwitzb59798b2003-03-21 01:43:31 +00006036/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00006037/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
6038#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00006039#define DEV_PTY_FILE "/dev/ptc"
6040#define HAVE_DEV_PTMX
6041#else
6042#define DEV_PTY_FILE "/dev/ptmx"
6043#endif
6044
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006045#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006046#ifdef HAVE_PTY_H
6047#include <pty.h>
6048#else
6049#ifdef HAVE_LIBUTIL_H
6050#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00006051#else
6052#ifdef HAVE_UTIL_H
6053#include <util.h>
6054#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006055#endif /* HAVE_LIBUTIL_H */
6056#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00006057#ifdef HAVE_STROPTS_H
6058#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006059#endif
6060#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006061
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006062#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006064"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006066
6067static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006068posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006069{
Victor Stinner8c62be82010-05-06 00:08:46 +00006070 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006071#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006072 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00006073#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006074#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006075 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006076#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006078#endif
6079#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00006080
Thomas Wouters70c21a12000-07-14 14:28:33 +00006081#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
6083 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006084#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
6086 if (slave_name == NULL)
6087 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00006088
Victor Stinner8c62be82010-05-06 00:08:46 +00006089 slave_fd = open(slave_name, O_RDWR);
6090 if (slave_fd < 0)
6091 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006092#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
6094 if (master_fd < 0)
6095 return posix_error();
6096 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
6097 /* change permission of slave */
6098 if (grantpt(master_fd) < 0) {
6099 PyOS_setsig(SIGCHLD, sig_saved);
6100 return posix_error();
6101 }
6102 /* unlock slave */
6103 if (unlockpt(master_fd) < 0) {
6104 PyOS_setsig(SIGCHLD, sig_saved);
6105 return posix_error();
6106 }
6107 PyOS_setsig(SIGCHLD, sig_saved);
6108 slave_name = ptsname(master_fd); /* get name of slave */
6109 if (slave_name == NULL)
6110 return posix_error();
6111 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
6112 if (slave_fd < 0)
6113 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00006114#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006115 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6116 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006117#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006118 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006119#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006120#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006121#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006122
Victor Stinner8c62be82010-05-06 00:08:46 +00006123 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006124
Fred Drake8cef4cf2000-06-28 16:40:38 +00006125}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006126#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006127
6128#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006129PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006130"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00006131Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
6132Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00006134
6135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006136posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006137{
Victor Stinner8c62be82010-05-06 00:08:46 +00006138 int master_fd = -1, result = 0;
6139 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006140
Victor Stinner8c62be82010-05-06 00:08:46 +00006141 _PyImport_AcquireLock();
6142 pid = forkpty(&master_fd, NULL, NULL, NULL);
6143 if (pid == 0) {
6144 /* child: this clobbers and resets the import lock. */
6145 PyOS_AfterFork();
6146 } else {
6147 /* parent: release the import lock. */
6148 result = _PyImport_ReleaseLock();
6149 }
6150 if (pid == -1)
6151 return posix_error();
6152 if (result < 0) {
6153 /* Don't clobber the OSError if the fork failed. */
6154 PyErr_SetString(PyExc_RuntimeError,
6155 "not holding the import lock");
6156 return NULL;
6157 }
6158 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006159}
6160#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006161
Ross Lagerwall7807c352011-03-17 20:20:30 +02006162
Guido van Rossumad0ee831995-03-01 10:34:45 +00006163#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006164PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006165"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006166Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006167
Barry Warsaw53699e91996-12-10 23:23:01 +00006168static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006169posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006170{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006171 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006172}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006173#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006175
Guido van Rossumad0ee831995-03-01 10:34:45 +00006176#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006177PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006178"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006179Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006180
Barry Warsaw53699e91996-12-10 23:23:01 +00006181static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006182posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006183{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006184 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006185}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006186#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006188
Guido van Rossumad0ee831995-03-01 10:34:45 +00006189#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006190PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006191"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006192Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Barry Warsaw53699e91996-12-10 23:23:01 +00006194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006195posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006196{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006197 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006198}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006199#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006201
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006202PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006203"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006204Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006205
Barry Warsaw53699e91996-12-10 23:23:01 +00006206static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006207posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006208{
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006210}
6211
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006212#ifdef HAVE_GETGROUPLIST
6213PyDoc_STRVAR(posix_getgrouplist__doc__,
6214"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6215Returns a list of groups to which a user belongs.\n\n\
6216 user: username to lookup\n\
6217 group: base group id of the user");
6218
6219static PyObject *
6220posix_getgrouplist(PyObject *self, PyObject *args)
6221{
6222#ifdef NGROUPS_MAX
6223#define MAX_GROUPS NGROUPS_MAX
6224#else
6225 /* defined to be 16 on Solaris7, so this should be a small number */
6226#define MAX_GROUPS 64
6227#endif
6228
6229 const char *user;
6230 int i, ngroups;
6231 PyObject *list;
6232#ifdef __APPLE__
6233 int *groups, basegid;
6234#else
6235 gid_t *groups, basegid;
6236#endif
6237 ngroups = MAX_GROUPS;
6238
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006239#ifdef __APPLE__
6240 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006241 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006242#else
6243 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6244 _Py_Gid_Converter, &basegid))
6245 return NULL;
6246#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006247
6248#ifdef __APPLE__
6249 groups = PyMem_Malloc(ngroups * sizeof(int));
6250#else
6251 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
6252#endif
6253 if (groups == NULL)
6254 return PyErr_NoMemory();
6255
6256 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6257 PyMem_Del(groups);
6258 return posix_error();
6259 }
6260
6261 list = PyList_New(ngroups);
6262 if (list == NULL) {
6263 PyMem_Del(groups);
6264 return NULL;
6265 }
6266
6267 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006268#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006269 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006270#else
6271 PyObject *o = _PyLong_FromGid(groups[i]);
6272#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006273 if (o == NULL) {
6274 Py_DECREF(list);
6275 PyMem_Del(groups);
6276 return NULL;
6277 }
6278 PyList_SET_ITEM(list, i, o);
6279 }
6280
6281 PyMem_Del(groups);
6282
6283 return list;
6284}
6285#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006286
Fred Drakec9680921999-12-13 16:37:25 +00006287#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006288PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006289"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006290Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00006291
6292static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006293posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00006294{
6295 PyObject *result = NULL;
6296
Fred Drakec9680921999-12-13 16:37:25 +00006297#ifdef NGROUPS_MAX
6298#define MAX_GROUPS NGROUPS_MAX
6299#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006301#define MAX_GROUPS 64
6302#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006303 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006304
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006305 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006306 * This is a helper variable to store the intermediate result when
6307 * that happens.
6308 *
6309 * To keep the code readable the OSX behaviour is unconditional,
6310 * according to the POSIX spec this should be safe on all unix-y
6311 * systems.
6312 */
6313 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006315
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006317 if (n < 0) {
6318 if (errno == EINVAL) {
6319 n = getgroups(0, NULL);
6320 if (n == -1) {
6321 return posix_error();
6322 }
6323 if (n == 0) {
6324 /* Avoid malloc(0) */
6325 alt_grouplist = grouplist;
6326 } else {
6327 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
6328 if (alt_grouplist == NULL) {
6329 errno = EINVAL;
6330 return posix_error();
6331 }
6332 n = getgroups(n, alt_grouplist);
6333 if (n == -1) {
6334 PyMem_Free(alt_grouplist);
6335 return posix_error();
6336 }
6337 }
6338 } else {
6339 return posix_error();
6340 }
6341 }
6342 result = PyList_New(n);
6343 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 int i;
6345 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006346 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006347 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006348 Py_DECREF(result);
6349 result = NULL;
6350 break;
Fred Drakec9680921999-12-13 16:37:25 +00006351 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006352 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006353 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006354 }
6355
6356 if (alt_grouplist != grouplist) {
6357 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006358 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006359
Fred Drakec9680921999-12-13 16:37:25 +00006360 return result;
6361}
6362#endif
6363
Antoine Pitroub7572f02009-12-02 20:46:48 +00006364#ifdef HAVE_INITGROUPS
6365PyDoc_STRVAR(posix_initgroups__doc__,
6366"initgroups(username, gid) -> None\n\n\
6367Call the system initgroups() to initialize the group access list with all of\n\
6368the groups of which the specified username is a member, plus the specified\n\
6369group id.");
6370
6371static PyObject *
6372posix_initgroups(PyObject *self, PyObject *args)
6373{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006374 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006375 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006376 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006377#ifdef __APPLE__
6378 int gid;
6379#else
6380 gid_t gid;
6381#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006382
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006383#ifdef __APPLE__
6384 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6385 PyUnicode_FSConverter, &oname,
6386 &gid))
6387#else
6388 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6389 PyUnicode_FSConverter, &oname,
6390 _Py_Gid_Converter, &gid))
6391#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006393 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006394
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006395 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006396 Py_DECREF(oname);
6397 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006399
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 Py_INCREF(Py_None);
6401 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006402}
6403#endif
6404
Martin v. Löwis606edc12002-06-13 21:09:11 +00006405#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006406PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006407"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00006408Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00006409
6410static PyObject *
6411posix_getpgid(PyObject *self, PyObject *args)
6412{
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 pid_t pid, pgid;
6414 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
6415 return NULL;
6416 pgid = getpgid(pid);
6417 if (pgid < 0)
6418 return posix_error();
6419 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006420}
6421#endif /* HAVE_GETPGID */
6422
6423
Guido van Rossumb6775db1994-08-01 11:34:53 +00006424#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006425PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006426"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006427Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006428
Barry Warsaw53699e91996-12-10 23:23:01 +00006429static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006430posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00006431{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006432#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006433 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006434#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006436#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006437}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006438#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006440
Guido van Rossumb6775db1994-08-01 11:34:53 +00006441#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006442PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006443"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00006444Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006445
Barry Warsaw53699e91996-12-10 23:23:01 +00006446static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006447posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006448{
Guido van Rossum64933891994-10-20 21:56:42 +00006449#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006451#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006453#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 return posix_error();
6455 Py_INCREF(Py_None);
6456 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006457}
6458
Guido van Rossumb6775db1994-08-01 11:34:53 +00006459#endif /* HAVE_SETPGRP */
6460
Guido van Rossumad0ee831995-03-01 10:34:45 +00006461#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006462
6463#ifdef MS_WINDOWS
6464#include <tlhelp32.h>
6465
6466static PyObject*
6467win32_getppid()
6468{
6469 HANDLE snapshot;
6470 pid_t mypid;
6471 PyObject* result = NULL;
6472 BOOL have_record;
6473 PROCESSENTRY32 pe;
6474
6475 mypid = getpid(); /* This function never fails */
6476
6477 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6478 if (snapshot == INVALID_HANDLE_VALUE)
6479 return PyErr_SetFromWindowsErr(GetLastError());
6480
6481 pe.dwSize = sizeof(pe);
6482 have_record = Process32First(snapshot, &pe);
6483 while (have_record) {
6484 if (mypid == (pid_t)pe.th32ProcessID) {
6485 /* We could cache the ulong value in a static variable. */
6486 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6487 break;
6488 }
6489
6490 have_record = Process32Next(snapshot, &pe);
6491 }
6492
6493 /* If our loop exits and our pid was not found (result will be NULL)
6494 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6495 * error anyway, so let's raise it. */
6496 if (!result)
6497 result = PyErr_SetFromWindowsErr(GetLastError());
6498
6499 CloseHandle(snapshot);
6500
6501 return result;
6502}
6503#endif /*MS_WINDOWS*/
6504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006505PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006506"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006507Return the parent's process id. If the parent process has already exited,\n\
6508Windows machines will still return its id; others systems will return the id\n\
6509of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006510
Barry Warsaw53699e91996-12-10 23:23:01 +00006511static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006512posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006513{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006514#ifdef MS_WINDOWS
6515 return win32_getppid();
6516#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006518#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006519}
6520#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006521
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006522
Fred Drake12c6e2d1999-12-14 21:25:03 +00006523#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006524PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006525"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006526Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00006527
6528static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006529posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006530{
Victor Stinner8c62be82010-05-06 00:08:46 +00006531 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006532#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006533 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006534 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006535
6536 if (GetUserNameW(user_name, &num_chars)) {
6537 /* num_chars is the number of unicode chars plus null terminator */
6538 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006539 }
6540 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006541 result = PyErr_SetFromWindowsErr(GetLastError());
6542#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 char *name;
6544 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006545
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 errno = 0;
6547 name = getlogin();
6548 if (name == NULL) {
6549 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006550 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006551 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006552 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 }
6554 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006555 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006557#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006558 return result;
6559}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006560#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006561
Guido van Rossumad0ee831995-03-01 10:34:45 +00006562#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006563PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006564"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006565Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006566
Barry Warsaw53699e91996-12-10 23:23:01 +00006567static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006568posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00006569{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006570 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006571}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006572#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00006573
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006574
Guido van Rossumad0ee831995-03-01 10:34:45 +00006575#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006576PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006577"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006578Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006579
Barry Warsaw53699e91996-12-10 23:23:01 +00006580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006581posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006582{
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 pid_t pid;
6584 int sig;
6585 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
6586 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006587#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006588 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
6589 APIRET rc;
6590 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006591 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006592
6593 } else if (sig == XCPT_SIGNAL_KILLPROC) {
6594 APIRET rc;
6595 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006596 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006597
6598 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00006599 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006600#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 if (kill(pid, sig) == -1)
6602 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006603#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 Py_INCREF(Py_None);
6605 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00006606}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006607#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006608
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006609#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006610PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006611"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006612Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006613
6614static PyObject *
6615posix_killpg(PyObject *self, PyObject *args)
6616{
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 int sig;
6618 pid_t pgid;
6619 /* XXX some man pages make the `pgid` parameter an int, others
6620 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6621 take the same type. Moreover, pid_t is always at least as wide as
6622 int (else compilation of this module fails), which is safe. */
6623 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
6624 return NULL;
6625 if (killpg(pgid, sig) == -1)
6626 return posix_error();
6627 Py_INCREF(Py_None);
6628 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006629}
6630#endif
6631
Brian Curtineb24d742010-04-12 17:16:38 +00006632#ifdef MS_WINDOWS
6633PyDoc_STRVAR(win32_kill__doc__,
6634"kill(pid, sig)\n\n\
6635Kill a process with a signal.");
6636
6637static PyObject *
6638win32_kill(PyObject *self, PyObject *args)
6639{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006640 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 DWORD pid, sig, err;
6642 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006643
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
6645 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00006646
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 /* Console processes which share a common console can be sent CTRL+C or
6648 CTRL+BREAK events, provided they handle said events. */
6649 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
6650 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
6651 err = GetLastError();
6652 PyErr_SetFromWindowsErr(err);
6653 }
6654 else
6655 Py_RETURN_NONE;
6656 }
Brian Curtineb24d742010-04-12 17:16:38 +00006657
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6659 attempt to open and terminate the process. */
6660 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
6661 if (handle == NULL) {
6662 err = GetLastError();
6663 return PyErr_SetFromWindowsErr(err);
6664 }
Brian Curtineb24d742010-04-12 17:16:38 +00006665
Victor Stinner8c62be82010-05-06 00:08:46 +00006666 if (TerminateProcess(handle, sig) == 0) {
6667 err = GetLastError();
6668 result = PyErr_SetFromWindowsErr(err);
6669 } else {
6670 Py_INCREF(Py_None);
6671 result = Py_None;
6672 }
Brian Curtineb24d742010-04-12 17:16:38 +00006673
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 CloseHandle(handle);
6675 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006676}
6677#endif /* MS_WINDOWS */
6678
Guido van Rossumc0125471996-06-28 18:55:32 +00006679#ifdef HAVE_PLOCK
6680
6681#ifdef HAVE_SYS_LOCK_H
6682#include <sys/lock.h>
6683#endif
6684
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006685PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006686"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006687Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006688
Barry Warsaw53699e91996-12-10 23:23:01 +00006689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006690posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00006691{
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 int op;
6693 if (!PyArg_ParseTuple(args, "i:plock", &op))
6694 return NULL;
6695 if (plock(op) == -1)
6696 return posix_error();
6697 Py_INCREF(Py_None);
6698 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00006699}
6700#endif
6701
Guido van Rossumb6775db1994-08-01 11:34:53 +00006702#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006703PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006704"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006705Set the current process's user id.");
6706
Barry Warsaw53699e91996-12-10 23:23:01 +00006707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006708posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006709{
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 uid_t uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006711 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 if (setuid(uid) < 0)
6714 return posix_error();
6715 Py_INCREF(Py_None);
6716 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006717}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006718#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006720
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006721#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006722PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006723"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006724Set the current process's effective user id.");
6725
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006726static PyObject *
6727posix_seteuid (PyObject *self, PyObject *args)
6728{
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 uid_t euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006730 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 if (seteuid(euid) < 0) {
6733 return posix_error();
6734 } else {
6735 Py_INCREF(Py_None);
6736 return Py_None;
6737 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006738}
6739#endif /* HAVE_SETEUID */
6740
6741#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006742PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006743"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006744Set the current process's effective group id.");
6745
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006746static PyObject *
6747posix_setegid (PyObject *self, PyObject *args)
6748{
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 gid_t egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006750 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 if (setegid(egid) < 0) {
6753 return posix_error();
6754 } else {
6755 Py_INCREF(Py_None);
6756 return Py_None;
6757 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006758}
6759#endif /* HAVE_SETEGID */
6760
6761#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006762PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006763"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006764Set the current process's real and effective user ids.");
6765
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006766static PyObject *
6767posix_setreuid (PyObject *self, PyObject *args)
6768{
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 uid_t ruid, euid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006770 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6771 _Py_Uid_Converter, &ruid,
6772 _Py_Uid_Converter, &euid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 if (setreuid(ruid, euid) < 0) {
6775 return posix_error();
6776 } else {
6777 Py_INCREF(Py_None);
6778 return Py_None;
6779 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006780}
6781#endif /* HAVE_SETREUID */
6782
6783#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006784PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006785"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006786Set the current process's real and effective group ids.");
6787
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006788static PyObject *
6789posix_setregid (PyObject *self, PyObject *args)
6790{
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 gid_t rgid, egid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006792 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6793 _Py_Gid_Converter, &rgid,
6794 _Py_Gid_Converter, &egid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 if (setregid(rgid, egid) < 0) {
6797 return posix_error();
6798 } else {
6799 Py_INCREF(Py_None);
6800 return Py_None;
6801 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006802}
6803#endif /* HAVE_SETREGID */
6804
Guido van Rossumb6775db1994-08-01 11:34:53 +00006805#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006806PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006807"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006808Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006809
Barry Warsaw53699e91996-12-10 23:23:01 +00006810static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006811posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006812{
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 gid_t gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006814 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 if (setgid(gid) < 0)
6817 return posix_error();
6818 Py_INCREF(Py_None);
6819 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006820}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006821#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006822
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006823#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006824PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006825"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006826Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006827
6828static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006829posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006830{
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 int i, len;
6832 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006833
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 if (!PySequence_Check(groups)) {
6835 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6836 return NULL;
6837 }
6838 len = PySequence_Size(groups);
6839 if (len > MAX_GROUPS) {
6840 PyErr_SetString(PyExc_ValueError, "too many groups");
6841 return NULL;
6842 }
6843 for(i = 0; i < len; i++) {
6844 PyObject *elem;
6845 elem = PySequence_GetItem(groups, i);
6846 if (!elem)
6847 return NULL;
6848 if (!PyLong_Check(elem)) {
6849 PyErr_SetString(PyExc_TypeError,
6850 "groups must be integers");
6851 Py_DECREF(elem);
6852 return NULL;
6853 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006854 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006855 Py_DECREF(elem);
6856 return NULL;
6857 }
6858 }
6859 Py_DECREF(elem);
6860 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006861
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 if (setgroups(len, grouplist) < 0)
6863 return posix_error();
6864 Py_INCREF(Py_None);
6865 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006866}
6867#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006868
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6870static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006871wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872{
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 PyObject *result;
6874 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006875 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 if (pid == -1)
6878 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006879
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 if (struct_rusage == NULL) {
6881 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6882 if (m == NULL)
6883 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006884 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006885 Py_DECREF(m);
6886 if (struct_rusage == NULL)
6887 return NULL;
6888 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006889
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6891 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6892 if (!result)
6893 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894
6895#ifndef doubletime
6896#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6897#endif
6898
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006900 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006902 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006903#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6905 SET_INT(result, 2, ru->ru_maxrss);
6906 SET_INT(result, 3, ru->ru_ixrss);
6907 SET_INT(result, 4, ru->ru_idrss);
6908 SET_INT(result, 5, ru->ru_isrss);
6909 SET_INT(result, 6, ru->ru_minflt);
6910 SET_INT(result, 7, ru->ru_majflt);
6911 SET_INT(result, 8, ru->ru_nswap);
6912 SET_INT(result, 9, ru->ru_inblock);
6913 SET_INT(result, 10, ru->ru_oublock);
6914 SET_INT(result, 11, ru->ru_msgsnd);
6915 SET_INT(result, 12, ru->ru_msgrcv);
6916 SET_INT(result, 13, ru->ru_nsignals);
6917 SET_INT(result, 14, ru->ru_nvcsw);
6918 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006919#undef SET_INT
6920
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 if (PyErr_Occurred()) {
6922 Py_DECREF(result);
6923 return NULL;
6924 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006927}
6928#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6929
6930#ifdef HAVE_WAIT3
6931PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006932"wait3(options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006933Wait for completion of a child process.");
6934
6935static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006936posix_wait3(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006937{
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 pid_t pid;
6939 int options;
6940 struct rusage ru;
6941 WAIT_TYPE status;
6942 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006943
Victor Stinner4195b5c2012-02-08 23:03:19 +01006944 if (!PyArg_ParseTuple(args, "i:wait3", &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006946
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 Py_BEGIN_ALLOW_THREADS
6948 pid = wait3(&status, options, &ru);
6949 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006950
Victor Stinner4195b5c2012-02-08 23:03:19 +01006951 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006952}
6953#endif /* HAVE_WAIT3 */
6954
6955#ifdef HAVE_WAIT4
6956PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006957"wait4(pid, options) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006958Wait for completion of a given child process.");
6959
6960static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006961posix_wait4(PyObject *self, PyObject *args)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006962{
Victor Stinner8c62be82010-05-06 00:08:46 +00006963 pid_t pid;
6964 int options;
6965 struct rusage ru;
6966 WAIT_TYPE status;
6967 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006968
Victor Stinner4195b5c2012-02-08 23:03:19 +01006969 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006971
Victor Stinner8c62be82010-05-06 00:08:46 +00006972 Py_BEGIN_ALLOW_THREADS
6973 pid = wait4(pid, &status, options, &ru);
6974 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006975
Victor Stinner4195b5c2012-02-08 23:03:19 +01006976 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006977}
6978#endif /* HAVE_WAIT4 */
6979
Ross Lagerwall7807c352011-03-17 20:20:30 +02006980#if defined(HAVE_WAITID) && !defined(__APPLE__)
6981PyDoc_STRVAR(posix_waitid__doc__,
6982"waitid(idtype, id, options) -> waitid_result\n\n\
6983Wait for the completion of one or more child processes.\n\n\
6984idtype can be P_PID, P_PGID or P_ALL.\n\
6985id specifies the pid to wait on.\n\
6986options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6987or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6988Returns either waitid_result or None if WNOHANG is specified and there are\n\
6989no children in a waitable state.");
6990
6991static PyObject *
6992posix_waitid(PyObject *self, PyObject *args)
6993{
6994 PyObject *result;
6995 idtype_t idtype;
6996 id_t id;
6997 int options, res;
6998 siginfo_t si;
6999 si.si_pid = 0;
7000 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
7001 return NULL;
7002 Py_BEGIN_ALLOW_THREADS
7003 res = waitid(idtype, id, &si, options);
7004 Py_END_ALLOW_THREADS
7005 if (res == -1)
7006 return posix_error();
7007
7008 if (si.si_pid == 0)
7009 Py_RETURN_NONE;
7010
7011 result = PyStructSequence_New(&WaitidResultType);
7012 if (!result)
7013 return NULL;
7014
7015 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007016 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007017 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7018 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7019 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7020 if (PyErr_Occurred()) {
7021 Py_DECREF(result);
7022 return NULL;
7023 }
7024
7025 return result;
7026}
7027#endif
7028
Guido van Rossumb6775db1994-08-01 11:34:53 +00007029#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007030PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007031"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007032Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007033
Barry Warsaw53699e91996-12-10 23:23:01 +00007034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007035posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00007036{
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 pid_t pid;
7038 int options;
7039 WAIT_TYPE status;
7040 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007041
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7043 return NULL;
7044 Py_BEGIN_ALLOW_THREADS
7045 pid = waitpid(pid, &status, options);
7046 Py_END_ALLOW_THREADS
7047 if (pid == -1)
7048 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007049
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007051}
7052
Tim Petersab034fa2002-02-01 11:27:43 +00007053#elif defined(HAVE_CWAIT)
7054
7055/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007056PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007057"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007058"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00007059
7060static PyObject *
7061posix_waitpid(PyObject *self, PyObject *args)
7062{
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 Py_intptr_t pid;
7064 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00007065
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
7067 return NULL;
7068 Py_BEGIN_ALLOW_THREADS
7069 pid = _cwait(&status, pid, options);
7070 Py_END_ALLOW_THREADS
7071 if (pid == -1)
7072 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007073
Victor Stinner8c62be82010-05-06 00:08:46 +00007074 /* shift the status left a byte so this is more like the POSIX waitpid */
7075 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007076}
7077#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007078
Guido van Rossumad0ee831995-03-01 10:34:45 +00007079#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007080PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007081"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007082Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007083
Barry Warsaw53699e91996-12-10 23:23:01 +00007084static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007085posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00007086{
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 pid_t pid;
7088 WAIT_TYPE status;
7089 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007090
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 Py_BEGIN_ALLOW_THREADS
7092 pid = wait(&status);
7093 Py_END_ALLOW_THREADS
7094 if (pid == -1)
7095 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007096
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007098}
Guido van Rossumad0ee831995-03-01 10:34:45 +00007099#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00007100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007101
Larry Hastings9cf065c2012-06-22 16:30:09 -07007102#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7103PyDoc_STRVAR(readlink__doc__,
7104"readlink(path, *, dir_fd=None) -> path\n\n\
7105Return a string representing the path to which the symbolic link points.\n\
7106\n\
7107If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7108 and path should be relative; path will then be relative to that directory.\n\
7109dir_fd may not be implemented on your platform.\n\
7110 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007111#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007112
Guido van Rossumb6775db1994-08-01 11:34:53 +00007113#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007114
Barry Warsaw53699e91996-12-10 23:23:01 +00007115static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007117{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118 path_t path;
7119 int dir_fd = DEFAULT_DIR_FD;
7120 char buffer[MAXPATHLEN];
7121 ssize_t length;
7122 PyObject *return_value = NULL;
7123 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007124
Larry Hastings9cf065c2012-06-22 16:30:09 -07007125 memset(&path, 0, sizeof(path));
7126 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7127 path_converter, &path,
7128#ifdef HAVE_READLINKAT
7129 dir_fd_converter, &dir_fd
7130#else
7131 dir_fd_unavailable, &dir_fd
7132#endif
7133 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00007134 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007135
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007137#ifdef HAVE_READLINKAT
7138 if (dir_fd != DEFAULT_DIR_FD)
7139 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007140 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007141#endif
7142 length = readlink(path.narrow, buffer, sizeof(buffer));
7143 Py_END_ALLOW_THREADS
7144
7145 if (length < 0) {
7146 return_value = path_posix_error("readlink", &path);
7147 goto exit;
7148 }
7149
7150 if (PyUnicode_Check(path.object))
7151 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7152 else
7153 return_value = PyBytes_FromStringAndSize(buffer, length);
7154exit:
7155 path_cleanup(&path);
7156 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007157}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007158
7159
Guido van Rossumb6775db1994-08-01 11:34:53 +00007160#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007162
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007164PyDoc_STRVAR(posix_symlink__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007165"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7166Create a symbolic link pointing to src named dst.\n\n\
7167target_is_directory is required on Windows if the target is to be\n\
7168 interpreted as a directory. (On Windows, symlink requires\n\
7169 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\
7170 target_is_directory is ignored on non-Windows platforms.\n\
7171\n\
7172If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7173 and path should be relative; path will then be relative to that directory.\n\
7174dir_fd may not be implemented on your platform.\n\
7175 If it is unavailable, using it will raise a NotImplementedError.");
7176
7177#if defined(MS_WINDOWS)
7178
7179/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7180static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7181static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
7182static int
7183check_CreateSymbolicLink()
7184{
7185 HINSTANCE hKernel32;
7186 /* only recheck */
7187 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7188 return 1;
7189 hKernel32 = GetModuleHandleW(L"KERNEL32");
7190 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7191 "CreateSymbolicLinkW");
7192 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7193 "CreateSymbolicLinkA");
7194 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7195}
7196
7197#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007198
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007199static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007200posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007201{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007202 path_t src;
7203 path_t dst;
7204 int dir_fd = DEFAULT_DIR_FD;
7205 int target_is_directory = 0;
7206 static char *keywords[] = {"src", "dst", "target_is_directory",
7207 "dir_fd", NULL};
7208 PyObject *return_value;
7209#ifdef MS_WINDOWS
7210 DWORD result;
7211#else
7212 int result;
7213#endif
7214
7215 memset(&src, 0, sizeof(src));
7216 src.argument_name = "src";
7217 memset(&dst, 0, sizeof(dst));
7218 dst.argument_name = "dst";
7219
7220#ifdef MS_WINDOWS
7221 if (!check_CreateSymbolicLink()) {
7222 PyErr_SetString(PyExc_NotImplementedError,
7223 "CreateSymbolicLink functions not found");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007224 return NULL;
7225 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007226 if (!win32_can_symlink) {
7227 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007228 return NULL;
7229 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007230#endif
7231
7232 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink",
7233 keywords,
7234 path_converter, &src,
7235 path_converter, &dst,
7236 &target_is_directory,
7237#ifdef HAVE_SYMLINKAT
7238 dir_fd_converter, &dir_fd
7239#else
7240 dir_fd_unavailable, &dir_fd
7241#endif
7242 ))
7243 return NULL;
7244
7245 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) {
7246 PyErr_SetString(PyExc_ValueError,
7247 "symlink: src and dst must be the same type");
7248 return_value = NULL;
7249 goto exit;
7250 }
7251
7252#ifdef MS_WINDOWS
7253 Py_BEGIN_ALLOW_THREADS
7254 if (dst.wide)
7255 result = Py_CreateSymbolicLinkW(dst.wide, src.wide,
7256 target_is_directory);
7257 else
7258 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow,
7259 target_is_directory);
7260 Py_END_ALLOW_THREADS
7261
7262 if (!result) {
7263 return_value = win32_error_object("symlink", src.object);
7264 goto exit;
7265 }
7266
7267#else
7268
7269 Py_BEGIN_ALLOW_THREADS
7270#if HAVE_SYMLINKAT
7271 if (dir_fd != DEFAULT_DIR_FD)
7272 result = symlinkat(src.narrow, dir_fd, dst.narrow);
7273 else
7274#endif
7275 result = symlink(src.narrow, dst.narrow);
7276 Py_END_ALLOW_THREADS
7277
7278 if (result) {
7279 return_value = path_error("symlink", &dst);
7280 goto exit;
7281 }
7282#endif
7283
7284 return_value = Py_None;
7285 Py_INCREF(Py_None);
7286 goto exit; /* silence "unused label" warning */
7287exit:
7288 path_cleanup(&src);
7289 path_cleanup(&dst);
7290 return return_value;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007291}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007292
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007293#endif /* HAVE_SYMLINK */
7294
Larry Hastings9cf065c2012-06-22 16:30:09 -07007295
Brian Curtind40e6f72010-07-08 21:39:08 +00007296#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7297
Brian Curtind40e6f72010-07-08 21:39:08 +00007298static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007299win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Brian Curtind40e6f72010-07-08 21:39:08 +00007300{
7301 wchar_t *path;
7302 DWORD n_bytes_returned;
7303 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02007304 PyObject *po, *result;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007305 int dir_fd;
Brian Curtind40e6f72010-07-08 21:39:08 +00007306 HANDLE reparse_point_handle;
7307
7308 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7309 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7310 wchar_t *print_name;
7311
Larry Hastings9cf065c2012-06-22 16:30:09 -07007312 static char *keywords[] = {"path", "dir_fd", NULL};
7313
7314 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7315 &po,
7316 dir_fd_unavailable, &dir_fd
7317 ))
Victor Stinnereb5657a2011-09-30 01:44:27 +02007318 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007319
Victor Stinnereb5657a2011-09-30 01:44:27 +02007320 path = PyUnicode_AsUnicode(po);
7321 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00007322 return NULL;
7323
7324 /* First get a handle to the reparse point */
7325 Py_BEGIN_ALLOW_THREADS
7326 reparse_point_handle = CreateFileW(
7327 path,
7328 0,
7329 0,
7330 0,
7331 OPEN_EXISTING,
7332 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7333 0);
7334 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007335
Brian Curtind40e6f72010-07-08 21:39:08 +00007336 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007337 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007338
Brian Curtind40e6f72010-07-08 21:39:08 +00007339 Py_BEGIN_ALLOW_THREADS
7340 /* New call DeviceIoControl to read the reparse point */
7341 io_result = DeviceIoControl(
7342 reparse_point_handle,
7343 FSCTL_GET_REPARSE_POINT,
7344 0, 0, /* in buffer */
7345 target_buffer, sizeof(target_buffer),
7346 &n_bytes_returned,
7347 0 /* we're not using OVERLAPPED_IO */
7348 );
7349 CloseHandle(reparse_point_handle);
7350 Py_END_ALLOW_THREADS
7351
7352 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02007353 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00007354
7355 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7356 {
7357 PyErr_SetString(PyExc_ValueError,
7358 "not a symbolic link");
7359 return NULL;
7360 }
Brian Curtin74e45612010-07-09 15:58:59 +00007361 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7362 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7363
7364 result = PyUnicode_FromWideChar(print_name,
7365 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00007366 return result;
7367}
7368
7369#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7370
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007371
Larry Hastings605a62d2012-06-24 04:33:36 -07007372static PyStructSequence_Field times_result_fields[] = {
7373 {"user", "user time"},
7374 {"system", "system time"},
7375 {"children_user", "user time of children"},
7376 {"children_system", "system time of children"},
7377 {"elapsed", "elapsed time since an arbitrary point in the past"},
7378 {NULL}
7379};
7380
7381PyDoc_STRVAR(times_result__doc__,
7382"times_result: Result from os.times().\n\n\
7383This object may be accessed either as a tuple of\n\
7384 (user, system, children_user, children_system, elapsed),\n\
7385or via the attributes user, system, children_user, children_system,\n\
7386and elapsed.\n\
7387\n\
7388See os.times for more information.");
7389
7390static PyStructSequence_Desc times_result_desc = {
7391 "times_result", /* name */
7392 times_result__doc__, /* doc */
7393 times_result_fields,
7394 5
7395};
7396
7397static PyTypeObject TimesResultType;
7398
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007399#ifdef MS_WINDOWS
7400#define HAVE_TIMES /* mandatory, for the method table */
7401#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007402
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007403#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007404
7405static PyObject *
7406build_times_result(double user, double system,
7407 double children_user, double children_system,
7408 double elapsed)
7409{
7410 PyObject *value = PyStructSequence_New(&TimesResultType);
7411 if (value == NULL)
7412 return NULL;
7413
7414#define SET(i, field) \
7415 { \
7416 PyObject *o = PyFloat_FromDouble(field); \
7417 if (!o) { \
7418 Py_DECREF(value); \
7419 return NULL; \
7420 } \
7421 PyStructSequence_SET_ITEM(value, i, o); \
7422 } \
7423
7424 SET(0, user);
7425 SET(1, system);
7426 SET(2, children_user);
7427 SET(3, children_system);
7428 SET(4, elapsed);
7429
7430#undef SET
7431
7432 return value;
7433}
7434
7435PyDoc_STRVAR(posix_times__doc__,
7436"times() -> times_result\n\n\
7437Return an object containing floating point numbers indicating process\n\
7438times. The object behaves like a named tuple with these fields:\n\
7439 (utime, stime, cutime, cstime, elapsed_time)");
7440
Guido van Rossumd48f2521997-12-05 22:19:34 +00007441#if defined(PYCC_VACPP) && defined(PYOS_OS2)
7442static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007443system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007444{
7445 ULONG value = 0;
7446
7447 Py_BEGIN_ALLOW_THREADS
7448 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
7449 Py_END_ALLOW_THREADS
7450
7451 return value;
7452}
7453
7454static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007455posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007456{
Guido van Rossumd48f2521997-12-05 22:19:34 +00007457 /* Currently Only Uptime is Provided -- Others Later */
Larry Hastings605a62d2012-06-24 04:33:36 -07007458 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007459 (double)0 /* t.tms_utime / HZ */,
7460 (double)0 /* t.tms_stime / HZ */,
7461 (double)0 /* t.tms_cutime / HZ */,
7462 (double)0 /* t.tms_cstime / HZ */,
7463 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007464}
Larry Hastings605a62d2012-06-24 04:33:36 -07007465#elif defined(MS_WINDOWS)
Barry Warsaw53699e91996-12-10 23:23:01 +00007466static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007467posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007468{
Victor Stinner8c62be82010-05-06 00:08:46 +00007469 FILETIME create, exit, kernel, user;
7470 HANDLE hProc;
7471 hProc = GetCurrentProcess();
7472 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7473 /* The fields of a FILETIME structure are the hi and lo part
7474 of a 64-bit value expressed in 100 nanosecond units.
7475 1e7 is one second in such units; 1e-7 the inverse.
7476 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7477 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007478 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007479 (double)(user.dwHighDateTime*429.4967296 +
7480 user.dwLowDateTime*1e-7),
7481 (double)(kernel.dwHighDateTime*429.4967296 +
7482 kernel.dwLowDateTime*1e-7),
7483 (double)0,
7484 (double)0,
7485 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007486}
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007487#else /* Neither Windows nor OS/2 */
7488#define NEED_TICKS_PER_SECOND
7489static long ticks_per_second = -1;
7490static PyObject *
7491posix_times(PyObject *self, PyObject *noargs)
7492{
7493 struct tms t;
7494 clock_t c;
7495 errno = 0;
7496 c = times(&t);
7497 if (c == (clock_t) -1)
7498 return posix_error();
7499 return build_times_result(
7500 (double)t.tms_utime / ticks_per_second,
7501 (double)t.tms_stime / ticks_per_second,
7502 (double)t.tms_cutime / ticks_per_second,
7503 (double)t.tms_cstime / ticks_per_second,
7504 (double)c / ticks_per_second);
7505}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007506#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007507
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007508#endif /* HAVE_TIMES */
7509
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007510
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007511#ifdef HAVE_GETSID
7512PyDoc_STRVAR(posix_getsid__doc__,
7513"getsid(pid) -> sid\n\n\
7514Call the system call getsid().");
7515
7516static PyObject *
7517posix_getsid(PyObject *self, PyObject *args)
7518{
Victor Stinner8c62be82010-05-06 00:08:46 +00007519 pid_t pid;
7520 int sid;
7521 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
7522 return NULL;
7523 sid = getsid(pid);
7524 if (sid < 0)
7525 return posix_error();
7526 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007527}
7528#endif /* HAVE_GETSID */
7529
7530
Guido van Rossumb6775db1994-08-01 11:34:53 +00007531#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007532PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007533"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007534Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007535
Barry Warsaw53699e91996-12-10 23:23:01 +00007536static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007537posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007538{
Victor Stinner8c62be82010-05-06 00:08:46 +00007539 if (setsid() < 0)
7540 return posix_error();
7541 Py_INCREF(Py_None);
7542 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007543}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007544#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007545
Guido van Rossumb6775db1994-08-01 11:34:53 +00007546#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007547PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007548"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007549Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007550
Barry Warsaw53699e91996-12-10 23:23:01 +00007551static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007552posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00007553{
Victor Stinner8c62be82010-05-06 00:08:46 +00007554 pid_t pid;
7555 int pgrp;
7556 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
7557 return NULL;
7558 if (setpgid(pid, pgrp) < 0)
7559 return posix_error();
7560 Py_INCREF(Py_None);
7561 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007562}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007563#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007565
Guido van Rossumb6775db1994-08-01 11:34:53 +00007566#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007567PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007568"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007569Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007570
Barry Warsaw53699e91996-12-10 23:23:01 +00007571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007572posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007573{
Victor Stinner8c62be82010-05-06 00:08:46 +00007574 int fd;
7575 pid_t pgid;
7576 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
7577 return NULL;
7578 pgid = tcgetpgrp(fd);
7579 if (pgid < 0)
7580 return posix_error();
7581 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007582}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007583#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007584
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007585
Guido van Rossumb6775db1994-08-01 11:34:53 +00007586#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007587PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007588"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007589Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007590
Barry Warsaw53699e91996-12-10 23:23:01 +00007591static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007592posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00007593{
Victor Stinner8c62be82010-05-06 00:08:46 +00007594 int fd;
7595 pid_t pgid;
7596 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
7597 return NULL;
7598 if (tcsetpgrp(fd, pgid) < 0)
7599 return posix_error();
7600 Py_INCREF(Py_None);
7601 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007602}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007603#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007604
Guido van Rossum687dd131993-05-17 08:34:16 +00007605/* Functions acting on file descriptors */
7606
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007607PyDoc_STRVAR(posix_open__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007608"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7609Open a file for low level IO. Returns a file handle (integer).\n\
7610\n\
7611If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7612 and path should be relative; path will then be relative to that directory.\n\
7613dir_fd may not be implemented on your platform.\n\
7614 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007615
Barry Warsaw53699e91996-12-10 23:23:01 +00007616static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007617posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007618{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007619 path_t path;
7620 int flags;
Victor Stinner8c62be82010-05-06 00:08:46 +00007621 int mode = 0777;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007622 int dir_fd = DEFAULT_DIR_FD;
Victor Stinner8c62be82010-05-06 00:08:46 +00007623 int fd;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007624 PyObject *return_value = NULL;
7625 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007626
Larry Hastings9cf065c2012-06-22 16:30:09 -07007627 memset(&path, 0, sizeof(path));
7628 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
7629 path_converter, &path,
7630 &flags, &mode,
7631#ifdef HAVE_OPENAT
7632 dir_fd_converter, &dir_fd
7633#else
7634 dir_fd_unavailable, &dir_fd
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007635#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07007636 ))
7637 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007638
Victor Stinner8c62be82010-05-06 00:08:46 +00007639 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007640#ifdef MS_WINDOWS
7641 if (path.wide)
7642 fd = _wopen(path.wide, flags, mode);
7643 else
7644#endif
7645#ifdef HAVE_OPENAT
7646 if (dir_fd != DEFAULT_DIR_FD)
7647 fd = openat(dir_fd, path.narrow, flags, mode);
7648 else
7649#endif
7650 fd = open(path.narrow, flags, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00007651 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00007652
Larry Hastings9cf065c2012-06-22 16:30:09 -07007653 if (fd == -1) {
7654#ifdef MS_WINDOWS
7655 /* force use of posix_error here for exact backwards compatibility */
7656 if (path.wide)
7657 return_value = posix_error();
7658 else
7659#endif
7660 return_value = path_error("open", &path);
7661 goto exit;
7662 }
7663
7664 return_value = PyLong_FromLong((long)fd);
7665
7666exit:
7667 path_cleanup(&path);
7668 return return_value;
7669}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007670
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007671PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007672"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007673Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007674
Barry Warsaw53699e91996-12-10 23:23:01 +00007675static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007676posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007677{
Victor Stinner8c62be82010-05-06 00:08:46 +00007678 int fd, res;
7679 if (!PyArg_ParseTuple(args, "i:close", &fd))
7680 return NULL;
7681 if (!_PyVerify_fd(fd))
7682 return posix_error();
7683 Py_BEGIN_ALLOW_THREADS
7684 res = close(fd);
7685 Py_END_ALLOW_THREADS
7686 if (res < 0)
7687 return posix_error();
7688 Py_INCREF(Py_None);
7689 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007690}
7691
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007692
Victor Stinner8c62be82010-05-06 00:08:46 +00007693PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00007694"closerange(fd_low, fd_high)\n\n\
7695Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
7696
7697static PyObject *
7698posix_closerange(PyObject *self, PyObject *args)
7699{
Victor Stinner8c62be82010-05-06 00:08:46 +00007700 int fd_from, fd_to, i;
7701 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
7702 return NULL;
7703 Py_BEGIN_ALLOW_THREADS
7704 for (i = fd_from; i < fd_to; i++)
7705 if (_PyVerify_fd(i))
7706 close(i);
7707 Py_END_ALLOW_THREADS
7708 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007709}
7710
7711
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007712PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007713"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007714Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007715
Barry Warsaw53699e91996-12-10 23:23:01 +00007716static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007717posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007718{
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 int fd;
7720 if (!PyArg_ParseTuple(args, "i:dup", &fd))
7721 return NULL;
7722 if (!_PyVerify_fd(fd))
7723 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 if (fd < 0)
7726 return posix_error();
7727 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007728}
7729
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007730
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007731PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00007732"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007733Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007734
Barry Warsaw53699e91996-12-10 23:23:01 +00007735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007736posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007737{
Victor Stinner8c62be82010-05-06 00:08:46 +00007738 int fd, fd2, res;
7739 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
7740 return NULL;
7741 if (!_PyVerify_fd_dup2(fd, fd2))
7742 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 if (res < 0)
7745 return posix_error();
7746 Py_INCREF(Py_None);
7747 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00007748}
7749
Ross Lagerwall7807c352011-03-17 20:20:30 +02007750#ifdef HAVE_LOCKF
7751PyDoc_STRVAR(posix_lockf__doc__,
7752"lockf(fd, cmd, len)\n\n\
7753Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
7754fd is an open file descriptor.\n\
7755cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
7756F_TEST.\n\
7757len specifies the section of the file to lock.");
7758
7759static PyObject *
7760posix_lockf(PyObject *self, PyObject *args)
7761{
7762 int fd, cmd, res;
7763 off_t len;
7764 if (!PyArg_ParseTuple(args, "iiO&:lockf",
7765 &fd, &cmd, _parse_off_t, &len))
7766 return NULL;
7767
7768 Py_BEGIN_ALLOW_THREADS
7769 res = lockf(fd, cmd, len);
7770 Py_END_ALLOW_THREADS
7771
7772 if (res < 0)
7773 return posix_error();
7774
7775 Py_RETURN_NONE;
7776}
7777#endif
7778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007779
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007780PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007781"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01007782Set the current position of a file descriptor.\n\
7783Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007784
Barry Warsaw53699e91996-12-10 23:23:01 +00007785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007786posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007787{
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007789#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007791#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00007793#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02007794 PyObject *posobj;
7795 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00007797#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7799 switch (how) {
7800 case 0: how = SEEK_SET; break;
7801 case 1: how = SEEK_CUR; break;
7802 case 2: how = SEEK_END; break;
7803 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007804#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007805
Ross Lagerwall8e749672011-03-17 21:54:07 +02007806#if !defined(HAVE_LARGEFILE_SUPPORT)
7807 pos = PyLong_AsLong(posobj);
7808#else
7809 pos = PyLong_AsLongLong(posobj);
7810#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007811 if (PyErr_Occurred())
7812 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007813
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 if (!_PyVerify_fd(fd))
7815 return posix_error();
7816 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007817#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007819#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007821#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 Py_END_ALLOW_THREADS
7823 if (res < 0)
7824 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007825
7826#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007827 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007828#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007830#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007831}
7832
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007833
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007834PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007835"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007836Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007837
Barry Warsaw53699e91996-12-10 23:23:01 +00007838static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007839posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007840{
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 int fd, size;
7842 Py_ssize_t n;
7843 PyObject *buffer;
7844 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7845 return NULL;
7846 if (size < 0) {
7847 errno = EINVAL;
7848 return posix_error();
7849 }
7850 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7851 if (buffer == NULL)
7852 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007853 if (!_PyVerify_fd(fd)) {
7854 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007856 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 Py_BEGIN_ALLOW_THREADS
7858 n = read(fd, PyBytes_AS_STRING(buffer), size);
7859 Py_END_ALLOW_THREADS
7860 if (n < 0) {
7861 Py_DECREF(buffer);
7862 return posix_error();
7863 }
7864 if (n != size)
7865 _PyBytes_Resize(&buffer, n);
7866 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007867}
7868
Ross Lagerwall7807c352011-03-17 20:20:30 +02007869#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7870 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007871static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007872iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7873{
7874 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007875 Py_ssize_t blen, total = 0;
7876
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007877 *iov = PyMem_New(struct iovec, cnt);
7878 if (*iov == NULL) {
7879 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007880 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007881 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007882
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007883 *buf = PyMem_New(Py_buffer, cnt);
7884 if (*buf == NULL) {
7885 PyMem_Del(*iov);
7886 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007887 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007888 }
7889
7890 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007891 PyObject *item = PySequence_GetItem(seq, i);
7892 if (item == NULL)
7893 goto fail;
7894 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7895 Py_DECREF(item);
7896 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007897 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007898 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007899 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007900 blen = (*buf)[i].len;
7901 (*iov)[i].iov_len = blen;
7902 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007903 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007904 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007905
7906fail:
7907 PyMem_Del(*iov);
7908 for (j = 0; j < i; j++) {
7909 PyBuffer_Release(&(*buf)[j]);
7910 }
7911 PyMem_Del(*buf);
7912 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007913}
7914
7915static void
7916iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7917{
7918 int i;
7919 PyMem_Del(iov);
7920 for (i = 0; i < cnt; i++) {
7921 PyBuffer_Release(&buf[i]);
7922 }
7923 PyMem_Del(buf);
7924}
7925#endif
7926
Ross Lagerwall7807c352011-03-17 20:20:30 +02007927#ifdef HAVE_READV
7928PyDoc_STRVAR(posix_readv__doc__,
7929"readv(fd, buffers) -> bytesread\n\n\
7930Read from a file descriptor into a number of writable buffers. buffers\n\
7931is an arbitrary sequence of writable buffers.\n\
7932Returns the total number of bytes read.");
7933
7934static PyObject *
7935posix_readv(PyObject *self, PyObject *args)
7936{
7937 int fd, cnt;
7938 Py_ssize_t n;
7939 PyObject *seq;
7940 struct iovec *iov;
7941 Py_buffer *buf;
7942
7943 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7944 return NULL;
7945 if (!PySequence_Check(seq)) {
7946 PyErr_SetString(PyExc_TypeError,
7947 "readv() arg 2 must be a sequence");
7948 return NULL;
7949 }
7950 cnt = PySequence_Size(seq);
7951
7952 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7953 return NULL;
7954
7955 Py_BEGIN_ALLOW_THREADS
7956 n = readv(fd, iov, cnt);
7957 Py_END_ALLOW_THREADS
7958
7959 iov_cleanup(iov, buf, cnt);
7960 return PyLong_FromSsize_t(n);
7961}
7962#endif
7963
7964#ifdef HAVE_PREAD
7965PyDoc_STRVAR(posix_pread__doc__,
7966"pread(fd, buffersize, offset) -> string\n\n\
7967Read from a file descriptor, fd, at a position of offset. It will read up\n\
7968to buffersize number of bytes. The file offset remains unchanged.");
7969
7970static PyObject *
7971posix_pread(PyObject *self, PyObject *args)
7972{
7973 int fd, size;
7974 off_t offset;
7975 Py_ssize_t n;
7976 PyObject *buffer;
7977 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7978 return NULL;
7979
7980 if (size < 0) {
7981 errno = EINVAL;
7982 return posix_error();
7983 }
7984 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7985 if (buffer == NULL)
7986 return NULL;
7987 if (!_PyVerify_fd(fd)) {
7988 Py_DECREF(buffer);
7989 return posix_error();
7990 }
7991 Py_BEGIN_ALLOW_THREADS
7992 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7993 Py_END_ALLOW_THREADS
7994 if (n < 0) {
7995 Py_DECREF(buffer);
7996 return posix_error();
7997 }
7998 if (n != size)
7999 _PyBytes_Resize(&buffer, n);
8000 return buffer;
8001}
8002#endif
8003
8004PyDoc_STRVAR(posix_write__doc__,
8005"write(fd, string) -> byteswritten\n\n\
8006Write a string to a file descriptor.");
8007
8008static PyObject *
8009posix_write(PyObject *self, PyObject *args)
8010{
8011 Py_buffer pbuf;
8012 int fd;
8013 Py_ssize_t size, len;
8014
8015 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
8016 return NULL;
8017 if (!_PyVerify_fd(fd)) {
8018 PyBuffer_Release(&pbuf);
8019 return posix_error();
8020 }
8021 len = pbuf.len;
8022 Py_BEGIN_ALLOW_THREADS
8023#if defined(MS_WIN64) || defined(MS_WINDOWS)
8024 if (len > INT_MAX)
8025 len = INT_MAX;
8026 size = write(fd, pbuf.buf, (int)len);
8027#else
8028 size = write(fd, pbuf.buf, len);
8029#endif
8030 Py_END_ALLOW_THREADS
8031 PyBuffer_Release(&pbuf);
8032 if (size < 0)
8033 return posix_error();
8034 return PyLong_FromSsize_t(size);
8035}
8036
8037#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008038PyDoc_STRVAR(posix_sendfile__doc__,
8039"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8040sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8041 -> byteswritten\n\
8042Copy nbytes bytes from file descriptor in to file descriptor out.");
8043
8044static PyObject *
8045posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8046{
8047 int in, out;
8048 Py_ssize_t ret;
8049 off_t offset;
8050
8051#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8052#ifndef __APPLE__
8053 Py_ssize_t len;
8054#endif
8055 PyObject *headers = NULL, *trailers = NULL;
8056 Py_buffer *hbuf, *tbuf;
8057 off_t sbytes;
8058 struct sf_hdtr sf;
8059 int flags = 0;
8060 sf.headers = NULL;
8061 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008062 static char *keywords[] = {"out", "in",
8063 "offset", "count",
8064 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065
8066#ifdef __APPLE__
8067 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008068 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008069#else
8070 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00008071 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008072#endif
8073 &headers, &trailers, &flags))
8074 return NULL;
8075 if (headers != NULL) {
8076 if (!PySequence_Check(headers)) {
8077 PyErr_SetString(PyExc_TypeError,
8078 "sendfile() headers must be a sequence or None");
8079 return NULL;
8080 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008081 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008082 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008083 if (sf.hdr_cnt > 0 &&
8084 !(i = iov_setup(&(sf.headers), &hbuf,
8085 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008086 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008087#ifdef __APPLE__
8088 sbytes += i;
8089#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008090 }
8091 }
8092 if (trailers != NULL) {
8093 if (!PySequence_Check(trailers)) {
8094 PyErr_SetString(PyExc_TypeError,
8095 "sendfile() trailers must be a sequence or None");
8096 return NULL;
8097 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008098 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008099 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008100 if (sf.trl_cnt > 0 &&
8101 !(i = iov_setup(&(sf.trailers), &tbuf,
8102 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008103 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008104#ifdef __APPLE__
8105 sbytes += i;
8106#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008107 }
8108 }
8109
8110 Py_BEGIN_ALLOW_THREADS
8111#ifdef __APPLE__
8112 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
8113#else
8114 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
8115#endif
8116 Py_END_ALLOW_THREADS
8117
8118 if (sf.headers != NULL)
8119 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8120 if (sf.trailers != NULL)
8121 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8122
8123 if (ret < 0) {
8124 if ((errno == EAGAIN) || (errno == EBUSY)) {
8125 if (sbytes != 0) {
8126 // some data has been sent
8127 goto done;
8128 }
8129 else {
8130 // no data has been sent; upper application is supposed
8131 // to retry on EAGAIN or EBUSY
8132 return posix_error();
8133 }
8134 }
8135 return posix_error();
8136 }
8137 goto done;
8138
8139done:
8140 #if !defined(HAVE_LARGEFILE_SUPPORT)
8141 return Py_BuildValue("l", sbytes);
8142 #else
8143 return Py_BuildValue("L", sbytes);
8144 #endif
8145
8146#else
8147 Py_ssize_t count;
8148 PyObject *offobj;
8149 static char *keywords[] = {"out", "in",
8150 "offset", "count", NULL};
8151 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8152 keywords, &out, &in, &offobj, &count))
8153 return NULL;
8154#ifdef linux
8155 if (offobj == Py_None) {
8156 Py_BEGIN_ALLOW_THREADS
8157 ret = sendfile(out, in, NULL, count);
8158 Py_END_ALLOW_THREADS
8159 if (ret < 0)
8160 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008161 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008162 }
8163#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008164 if (!_parse_off_t(offobj, &offset))
8165 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008166 Py_BEGIN_ALLOW_THREADS
8167 ret = sendfile(out, in, &offset, count);
8168 Py_END_ALLOW_THREADS
8169 if (ret < 0)
8170 return posix_error();
8171 return Py_BuildValue("n", ret);
8172#endif
8173}
8174#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008175
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008176PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinner4195b5c2012-02-08 23:03:19 +01008177"fstat(fd) -> stat result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008178Like stat(), but for an open file descriptor.\n\
8179Equivalent to stat(fd=fd).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008180
Barry Warsaw53699e91996-12-10 23:23:01 +00008181static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01008182posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00008183{
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 int fd;
8185 STRUCT_STAT st;
8186 int res;
Victor Stinner4195b5c2012-02-08 23:03:19 +01008187 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008189#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 /* on OpenVMS we must ensure that all bytes are written to the file */
8191 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00008192#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 Py_BEGIN_ALLOW_THREADS
8194 res = FSTAT(fd, &st);
8195 Py_END_ALLOW_THREADS
8196 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008197#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008198 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00008199#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008200 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00008201#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 }
Tim Peters5aa91602002-01-30 05:46:57 +00008203
Victor Stinner4195b5c2012-02-08 23:03:19 +01008204 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008205}
8206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008207PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008208"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008209Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008210connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00008211
8212static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00008213posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00008214{
Victor Stinner8c62be82010-05-06 00:08:46 +00008215 int fd;
8216 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
8217 return NULL;
8218 if (!_PyVerify_fd(fd))
8219 return PyBool_FromLong(0);
8220 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00008221}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008222
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008223#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008224PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008225"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008226Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008227
Barry Warsaw53699e91996-12-10 23:23:01 +00008228static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008229posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00008230{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008231#if defined(PYOS_OS2)
8232 HFILE read, write;
8233 APIRET rc;
8234
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008235 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008236 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008237 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008238
8239 return Py_BuildValue("(ii)", read, write);
8240#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008241#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008242 int fds[2];
8243 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00008245 if (res != 0)
8246 return posix_error();
8247 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008248#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00008249 HANDLE read, write;
8250 int read_fd, write_fd;
8251 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 if (!ok)
8254 return win32_error("CreatePipe", NULL);
8255 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
8256 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
8257 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008258#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008259#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00008260}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008261#endif /* HAVE_PIPE */
8262
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008263#ifdef HAVE_PIPE2
8264PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02008265"pipe2(flags) -> (read_end, write_end)\n\n\
8266Create a pipe with flags set atomically.\n\
8267flags can be constructed by ORing together one or more of these values:\n\
8268O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008269");
8270
8271static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02008272posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008273{
Charles-François Natali368f34b2011-06-06 19:49:47 +02008274 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008275 int fds[2];
8276 int res;
8277
Serhiy Storchaka9101e232013-01-19 12:41:45 +02008278 flags = _PyLong_AsInt(arg);
Charles-François Natali368f34b2011-06-06 19:49:47 +02008279 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008280 return NULL;
8281
8282 res = pipe2(fds, flags);
8283 if (res != 0)
8284 return posix_error();
8285 return Py_BuildValue("(ii)", fds[0], fds[1]);
8286}
8287#endif /* HAVE_PIPE2 */
8288
Ross Lagerwall7807c352011-03-17 20:20:30 +02008289#ifdef HAVE_WRITEV
8290PyDoc_STRVAR(posix_writev__doc__,
8291"writev(fd, buffers) -> byteswritten\n\n\
8292Write the contents of buffers to a file descriptor, where buffers is an\n\
8293arbitrary sequence of buffers.\n\
8294Returns the total bytes written.");
8295
8296static PyObject *
8297posix_writev(PyObject *self, PyObject *args)
8298{
8299 int fd, cnt;
8300 Py_ssize_t res;
8301 PyObject *seq;
8302 struct iovec *iov;
8303 Py_buffer *buf;
8304 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
8305 return NULL;
8306 if (!PySequence_Check(seq)) {
8307 PyErr_SetString(PyExc_TypeError,
8308 "writev() arg 2 must be a sequence");
8309 return NULL;
8310 }
8311 cnt = PySequence_Size(seq);
8312
8313 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
8314 return NULL;
8315 }
8316
8317 Py_BEGIN_ALLOW_THREADS
8318 res = writev(fd, iov, cnt);
8319 Py_END_ALLOW_THREADS
8320
8321 iov_cleanup(iov, buf, cnt);
8322 return PyLong_FromSsize_t(res);
8323}
8324#endif
8325
8326#ifdef HAVE_PWRITE
8327PyDoc_STRVAR(posix_pwrite__doc__,
8328"pwrite(fd, string, offset) -> byteswritten\n\n\
8329Write string to a file descriptor, fd, from offset, leaving the file\n\
8330offset unchanged.");
8331
8332static PyObject *
8333posix_pwrite(PyObject *self, PyObject *args)
8334{
8335 Py_buffer pbuf;
8336 int fd;
8337 off_t offset;
8338 Py_ssize_t size;
8339
8340 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
8341 return NULL;
8342
8343 if (!_PyVerify_fd(fd)) {
8344 PyBuffer_Release(&pbuf);
8345 return posix_error();
8346 }
8347 Py_BEGIN_ALLOW_THREADS
8348 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
8349 Py_END_ALLOW_THREADS
8350 PyBuffer_Release(&pbuf);
8351 if (size < 0)
8352 return posix_error();
8353 return PyLong_FromSsize_t(size);
8354}
8355#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008356
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008357#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008358PyDoc_STRVAR(posix_mkfifo__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008359"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\
8360Create a FIFO (a POSIX named pipe).\n\
8361\n\
8362If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8363 and path should be relative; path will then be relative to that directory.\n\
8364dir_fd may not be implemented on your platform.\n\
8365 If it is unavailable, using it will raise a NotImplementedError.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008366
Barry Warsaw53699e91996-12-10 23:23:01 +00008367static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008368posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008369{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008370 path_t path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008371 int mode = 0666;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008372 int dir_fd = DEFAULT_DIR_FD;
8373 int result;
8374 PyObject *return_value = NULL;
8375 static char *keywords[] = {"path", "mode", "dir_fd", NULL};
8376
8377 memset(&path, 0, sizeof(path));
8378 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords,
8379 path_converter, &path,
8380 &mode,
8381#ifdef HAVE_MKFIFOAT
8382 dir_fd_converter, &dir_fd
8383#else
8384 dir_fd_unavailable, &dir_fd
8385#endif
8386 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008387 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008388
Victor Stinner8c62be82010-05-06 00:08:46 +00008389 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008390#ifdef HAVE_MKFIFOAT
8391 if (dir_fd != DEFAULT_DIR_FD)
8392 result = mkfifoat(dir_fd, path.narrow, mode);
8393 else
8394#endif
8395 result = mkfifo(path.narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00008396 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008397
8398 if (result < 0) {
8399 return_value = posix_error();
8400 goto exit;
8401 }
8402
8403 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008404 Py_INCREF(Py_None);
Larry Hastings9cf065c2012-06-22 16:30:09 -07008405
8406exit:
8407 path_cleanup(&path);
8408 return return_value;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008409}
8410#endif
8411
Neal Norwitz11690112002-07-30 01:08:28 +00008412#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008413PyDoc_STRVAR(posix_mknod__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07008414"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008415Create a filesystem node (file, device special file or named pipe)\n\
8416named filename. mode specifies both the permissions to use and the\n\
8417type of node to be created, being combined (bitwise OR) with one of\n\
8418S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008419device defines the newly created device special file (probably using\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07008420os.makedev()), otherwise it is ignored.\n\
8421\n\
8422If dir_fd is not None, it should be a file descriptor open to a directory,\n\
8423 and path should be relative; path will then be relative to that directory.\n\
8424dir_fd may not be implemented on your platform.\n\
8425 If it is unavailable, using it will raise a NotImplementedError.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008426
8427
8428static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07008429posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008430{
Larry Hastings9cf065c2012-06-22 16:30:09 -07008431 path_t path;
8432 int mode = 0666;
Victor Stinner8c62be82010-05-06 00:08:46 +00008433 int device = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008434 int dir_fd = DEFAULT_DIR_FD;
8435 int result;
8436 PyObject *return_value = NULL;
8437 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL};
8438
8439 memset(&path, 0, sizeof(path));
8440 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords,
8441 path_converter, &path,
8442 &mode, &device,
8443#ifdef HAVE_MKNODAT
8444 dir_fd_converter, &dir_fd
8445#else
8446 dir_fd_unavailable, &dir_fd
8447#endif
8448 ))
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07008450
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008452#ifdef HAVE_MKNODAT
8453 if (dir_fd != DEFAULT_DIR_FD)
8454 result = mknodat(dir_fd, path.narrow, mode, device);
8455 else
8456#endif
8457 result = mknod(path.narrow, mode, device);
Victor Stinner8c62be82010-05-06 00:08:46 +00008458 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07008459
8460 if (result < 0) {
8461 return_value = posix_error();
8462 goto exit;
8463 }
8464
8465 return_value = Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00008466 Py_INCREF(Py_None);
Georg Brandlf7875592012-06-24 13:58:31 +02008467
Larry Hastings9cf065c2012-06-22 16:30:09 -07008468exit:
8469 path_cleanup(&path);
8470 return return_value;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008471}
8472#endif
8473
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008474#ifdef HAVE_DEVICE_MACROS
8475PyDoc_STRVAR(posix_major__doc__,
8476"major(device) -> major number\n\
8477Extracts a device major number from a raw device number.");
8478
8479static PyObject *
8480posix_major(PyObject *self, PyObject *args)
8481{
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 int device;
8483 if (!PyArg_ParseTuple(args, "i:major", &device))
8484 return NULL;
8485 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008486}
8487
8488PyDoc_STRVAR(posix_minor__doc__,
8489"minor(device) -> minor number\n\
8490Extracts a device minor number from a raw device number.");
8491
8492static PyObject *
8493posix_minor(PyObject *self, PyObject *args)
8494{
Victor Stinner8c62be82010-05-06 00:08:46 +00008495 int device;
8496 if (!PyArg_ParseTuple(args, "i:minor", &device))
8497 return NULL;
8498 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008499}
8500
8501PyDoc_STRVAR(posix_makedev__doc__,
8502"makedev(major, minor) -> device number\n\
8503Composes a raw device number from the major and minor device numbers.");
8504
8505static PyObject *
8506posix_makedev(PyObject *self, PyObject *args)
8507{
Victor Stinner8c62be82010-05-06 00:08:46 +00008508 int major, minor;
8509 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
8510 return NULL;
8511 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008512}
8513#endif /* device macros */
8514
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008515
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008516#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008517PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008518"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008519Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008520
Barry Warsaw53699e91996-12-10 23:23:01 +00008521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008522posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008523{
Victor Stinner8c62be82010-05-06 00:08:46 +00008524 int fd;
8525 off_t length;
8526 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008527
Ross Lagerwall7807c352011-03-17 20:20:30 +02008528 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008530
Victor Stinner8c62be82010-05-06 00:08:46 +00008531 Py_BEGIN_ALLOW_THREADS
8532 res = ftruncate(fd, length);
8533 Py_END_ALLOW_THREADS
8534 if (res < 0)
8535 return posix_error();
8536 Py_INCREF(Py_None);
8537 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008538}
8539#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00008540
Ross Lagerwall7807c352011-03-17 20:20:30 +02008541#ifdef HAVE_TRUNCATE
8542PyDoc_STRVAR(posix_truncate__doc__,
8543"truncate(path, length)\n\n\
Georg Brandl306336b2012-06-24 12:55:33 +02008544Truncate the file given by path to length bytes.\n\
8545On some platforms, path may also be specified as an open file descriptor.\n\
8546 If this functionality is unavailable, using it raises an exception.");
Ross Lagerwall7807c352011-03-17 20:20:30 +02008547
8548static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02008549posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008550{
Georg Brandl306336b2012-06-24 12:55:33 +02008551 path_t path;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008552 off_t length;
8553 int res;
Georg Brandl306336b2012-06-24 12:55:33 +02008554 PyObject *result = NULL;
8555 static char *keywords[] = {"path", "length", NULL};
Ross Lagerwall7807c352011-03-17 20:20:30 +02008556
Georg Brandl306336b2012-06-24 12:55:33 +02008557 memset(&path, 0, sizeof(path));
8558#ifdef HAVE_FTRUNCATE
8559 path.allow_fd = 1;
8560#endif
8561 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords,
8562 path_converter, &path,
8563 _parse_off_t, &length))
Ross Lagerwall7807c352011-03-17 20:20:30 +02008564 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008565
8566 Py_BEGIN_ALLOW_THREADS
Georg Brandl306336b2012-06-24 12:55:33 +02008567#ifdef HAVE_FTRUNCATE
8568 if (path.fd != -1)
8569 res = ftruncate(path.fd, length);
8570 else
8571#endif
8572 res = truncate(path.narrow, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008573 Py_END_ALLOW_THREADS
Ross Lagerwall7807c352011-03-17 20:20:30 +02008574 if (res < 0)
Georg Brandl306336b2012-06-24 12:55:33 +02008575 result = path_posix_error("truncate", &path);
8576 else {
8577 Py_INCREF(Py_None);
8578 result = Py_None;
8579 }
8580 path_cleanup(&path);
8581 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008582}
8583#endif
8584
8585#ifdef HAVE_POSIX_FALLOCATE
8586PyDoc_STRVAR(posix_posix_fallocate__doc__,
8587"posix_fallocate(fd, offset, len)\n\n\
8588Ensures that enough disk space is allocated for the file specified by fd\n\
8589starting from offset and continuing for len bytes.");
8590
8591static PyObject *
8592posix_posix_fallocate(PyObject *self, PyObject *args)
8593{
8594 off_t len, offset;
8595 int res, fd;
8596
8597 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
8598 &fd, _parse_off_t, &offset, _parse_off_t, &len))
8599 return NULL;
8600
8601 Py_BEGIN_ALLOW_THREADS
8602 res = posix_fallocate(fd, offset, len);
8603 Py_END_ALLOW_THREADS
8604 if (res != 0) {
8605 errno = res;
8606 return posix_error();
8607 }
8608 Py_RETURN_NONE;
8609}
8610#endif
8611
8612#ifdef HAVE_POSIX_FADVISE
8613PyDoc_STRVAR(posix_posix_fadvise__doc__,
8614"posix_fadvise(fd, offset, len, advice)\n\n\
8615Announces an intention to access data in a specific pattern thus allowing\n\
8616the kernel to make optimizations.\n\
8617The advice applies to the region of the file specified by fd starting at\n\
8618offset and continuing for len bytes.\n\
8619advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
8620POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
8621POSIX_FADV_DONTNEED.");
8622
8623static PyObject *
8624posix_posix_fadvise(PyObject *self, PyObject *args)
8625{
8626 off_t len, offset;
8627 int res, fd, advice;
8628
8629 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
8630 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
8631 return NULL;
8632
8633 Py_BEGIN_ALLOW_THREADS
8634 res = posix_fadvise(fd, offset, len, advice);
8635 Py_END_ALLOW_THREADS
8636 if (res != 0) {
8637 errno = res;
8638 return posix_error();
8639 }
8640 Py_RETURN_NONE;
8641}
8642#endif
8643
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008644#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008645PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008646"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008647Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008648
Fred Drake762e2061999-08-26 17:23:54 +00008649/* Save putenv() parameters as values here, so we can collect them when they
8650 * get re-set with another call for the same key. */
8651static PyObject *posix_putenv_garbage;
8652
Tim Peters5aa91602002-01-30 05:46:57 +00008653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008654posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008655{
Victor Stinner84ae1182010-05-06 22:05:07 +00008656 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008657#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01008658 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008659 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01008660
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008662 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01008663 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008665
Victor Stinner65170952011-11-22 22:16:17 +01008666 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00008667 if (newstr == NULL) {
8668 PyErr_NoMemory();
8669 goto error;
8670 }
Victor Stinner65170952011-11-22 22:16:17 +01008671 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
8672 PyErr_Format(PyExc_ValueError,
8673 "the environment variable is longer than %u characters",
8674 _MAX_ENV);
8675 goto error;
8676 }
8677
Victor Stinner8c62be82010-05-06 00:08:46 +00008678 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02008679 if (newenv == NULL)
8680 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008681 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008683 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008684 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008685#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008686 PyObject *os1, *os2;
8687 char *s1, *s2;
8688 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008689
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008690 if (!PyArg_ParseTuple(args,
8691 "O&O&:putenv",
8692 PyUnicode_FSConverter, &os1,
8693 PyUnicode_FSConverter, &os2))
8694 return NULL;
8695 s1 = PyBytes_AsString(os1);
8696 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00008697
Victor Stinner65170952011-11-22 22:16:17 +01008698 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01008699 if (newstr == NULL) {
8700 PyErr_NoMemory();
8701 goto error;
8702 }
8703
Victor Stinner8c62be82010-05-06 00:08:46 +00008704 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00008705 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008707 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008709#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008710
Victor Stinner8c62be82010-05-06 00:08:46 +00008711 /* Install the first arg and newstr in posix_putenv_garbage;
8712 * this will cause previous value to be collected. This has to
8713 * happen after the real putenv() call because the old value
8714 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01008715 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008716 /* really not much we can do; just leak */
8717 PyErr_Clear();
8718 }
8719 else {
8720 Py_DECREF(newstr);
8721 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00008722
Martin v. Löwis011e8422009-05-05 04:43:17 +00008723#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 Py_DECREF(os1);
8725 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00008726#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008727 Py_RETURN_NONE;
8728
8729error:
8730#ifndef MS_WINDOWS
8731 Py_DECREF(os1);
8732 Py_DECREF(os2);
8733#endif
8734 Py_XDECREF(newstr);
8735 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00008736}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008737#endif /* putenv */
8738
Guido van Rossumc524d952001-10-19 01:31:59 +00008739#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008740PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008741"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008742Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00008743
8744static PyObject *
8745posix_unsetenv(PyObject *self, PyObject *args)
8746{
Victor Stinner65170952011-11-22 22:16:17 +01008747 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01008748#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008749 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008750#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008751
8752 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00008753
Victor Stinner65170952011-11-22 22:16:17 +01008754 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00008755 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00008756
Victor Stinner984890f2011-11-24 13:53:38 +01008757#ifdef HAVE_BROKEN_UNSETENV
8758 unsetenv(PyBytes_AS_STRING(name));
8759#else
Victor Stinner65170952011-11-22 22:16:17 +01008760 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008761 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06008762 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01008763 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06008764 }
Victor Stinner984890f2011-11-24 13:53:38 +01008765#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008766
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 /* Remove the key from posix_putenv_garbage;
8768 * this will cause it to be collected. This has to
8769 * happen after the real unsetenv() call because the
8770 * old value was still accessible until then.
8771 */
Victor Stinner65170952011-11-22 22:16:17 +01008772 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008773 /* really not much we can do; just leak */
8774 PyErr_Clear();
8775 }
Victor Stinner65170952011-11-22 22:16:17 +01008776 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00008777 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008778}
8779#endif /* unsetenv */
8780
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008781PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008782"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008783Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008784
Guido van Rossumf68d8e52001-04-14 17:55:09 +00008785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008786posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00008787{
Victor Stinner8c62be82010-05-06 00:08:46 +00008788 int code;
8789 char *message;
8790 if (!PyArg_ParseTuple(args, "i:strerror", &code))
8791 return NULL;
8792 message = strerror(code);
8793 if (message == NULL) {
8794 PyErr_SetString(PyExc_ValueError,
8795 "strerror() argument out of range");
8796 return NULL;
8797 }
Victor Stinner1b579672011-12-17 05:47:23 +01008798 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008799}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008800
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008801
Guido van Rossumc9641791998-08-04 15:26:23 +00008802#ifdef HAVE_SYS_WAIT_H
8803
Fred Drake106c1a02002-04-23 15:58:02 +00008804#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008805PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008806"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008807Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00008808
8809static PyObject *
8810posix_WCOREDUMP(PyObject *self, PyObject *args)
8811{
Victor Stinner8c62be82010-05-06 00:08:46 +00008812 WAIT_TYPE status;
8813 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008814
Victor Stinner8c62be82010-05-06 00:08:46 +00008815 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
8816 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008817
Victor Stinner8c62be82010-05-06 00:08:46 +00008818 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008819}
8820#endif /* WCOREDUMP */
8821
8822#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008823PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008824"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00008825Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008826job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00008827
8828static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008829posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00008830{
Victor Stinner8c62be82010-05-06 00:08:46 +00008831 WAIT_TYPE status;
8832 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00008833
Victor Stinner8c62be82010-05-06 00:08:46 +00008834 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
8835 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00008836
Victor Stinner8c62be82010-05-06 00:08:46 +00008837 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00008838}
8839#endif /* WIFCONTINUED */
8840
Guido van Rossumc9641791998-08-04 15:26:23 +00008841#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008842PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008843"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008844Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008845
8846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008847posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008848{
Victor Stinner8c62be82010-05-06 00:08:46 +00008849 WAIT_TYPE status;
8850 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008851
Victor Stinner8c62be82010-05-06 00:08:46 +00008852 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
8853 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008854
Victor Stinner8c62be82010-05-06 00:08:46 +00008855 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008856}
8857#endif /* WIFSTOPPED */
8858
8859#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008860PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008861"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008862Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008863
8864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008865posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008866{
Victor Stinner8c62be82010-05-06 00:08:46 +00008867 WAIT_TYPE status;
8868 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008869
Victor Stinner8c62be82010-05-06 00:08:46 +00008870 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8871 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008872
Victor Stinner8c62be82010-05-06 00:08:46 +00008873 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008874}
8875#endif /* WIFSIGNALED */
8876
8877#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008878PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008879"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008880Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008881system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008882
8883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008884posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008885{
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 WAIT_TYPE status;
8887 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008888
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8890 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008891
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008893}
8894#endif /* WIFEXITED */
8895
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008896#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008897PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008898"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008899Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008900
8901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008902posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008903{
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 WAIT_TYPE status;
8905 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008906
Victor Stinner8c62be82010-05-06 00:08:46 +00008907 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8908 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008909
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008911}
8912#endif /* WEXITSTATUS */
8913
8914#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008915PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008916"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008917Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008918value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008919
8920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008921posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008922{
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 WAIT_TYPE status;
8924 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008925
Victor Stinner8c62be82010-05-06 00:08:46 +00008926 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8927 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008928
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008930}
8931#endif /* WTERMSIG */
8932
8933#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008934PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008935"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008936Return the signal that stopped the process that provided\n\
8937the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008938
8939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008940posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008941{
Victor Stinner8c62be82010-05-06 00:08:46 +00008942 WAIT_TYPE status;
8943 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008944
Victor Stinner8c62be82010-05-06 00:08:46 +00008945 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8946 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008947
Victor Stinner8c62be82010-05-06 00:08:46 +00008948 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008949}
8950#endif /* WSTOPSIG */
8951
8952#endif /* HAVE_SYS_WAIT_H */
8953
8954
Thomas Wouters477c8d52006-05-27 19:21:47 +00008955#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008956#ifdef _SCO_DS
8957/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8958 needed definitions in sys/statvfs.h */
8959#define _SVID3
8960#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008961#include <sys/statvfs.h>
8962
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008963static PyObject*
8964_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8966 if (v == NULL)
8967 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008968
8969#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8971 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8972 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8973 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8974 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8975 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8976 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8977 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8978 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8979 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008980#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008981 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8982 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8983 PyStructSequence_SET_ITEM(v, 2,
8984 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8985 PyStructSequence_SET_ITEM(v, 3,
8986 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8987 PyStructSequence_SET_ITEM(v, 4,
8988 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8989 PyStructSequence_SET_ITEM(v, 5,
8990 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8991 PyStructSequence_SET_ITEM(v, 6,
8992 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8993 PyStructSequence_SET_ITEM(v, 7,
8994 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8995 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8996 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008997#endif
8998
Victor Stinner8c62be82010-05-06 00:08:46 +00008999 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009000}
9001
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009002PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009003"fstatvfs(fd) -> statvfs result\n\n\
Larry Hastings9cf065c2012-06-22 16:30:09 -07009004Perform an fstatvfs system call on the given fd.\n\
9005Equivalent to statvfs(fd).");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009006
9007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009008posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009009{
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 int fd, res;
9011 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009012
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
9014 return NULL;
9015 Py_BEGIN_ALLOW_THREADS
9016 res = fstatvfs(fd, &st);
9017 Py_END_ALLOW_THREADS
9018 if (res != 0)
9019 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009020
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009022}
Thomas Wouters477c8d52006-05-27 19:21:47 +00009023#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009024
9025
Thomas Wouters477c8d52006-05-27 19:21:47 +00009026#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009027#include <sys/statvfs.h>
9028
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009029PyDoc_STRVAR(posix_statvfs__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07009030"statvfs(path)\n\n\
9031Perform a statvfs system call on the given path.\n\
9032\n\
9033path may always be specified as a string.\n\
9034On some platforms, path may also be specified as an open file descriptor.\n\
9035 If this functionality is unavailable, using it raises an exception.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00009036
9037static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07009038posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009039{
Larry Hastings9cf065c2012-06-22 16:30:09 -07009040 static char *keywords[] = {"path", NULL};
9041 path_t path;
9042 int result;
9043 PyObject *return_value = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009044 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009045
Larry Hastings9cf065c2012-06-22 16:30:09 -07009046 memset(&path, 0, sizeof(path));
9047#ifdef HAVE_FSTATVFS
9048 path.allow_fd = 1;
9049#endif
9050 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords,
9051 path_converter, &path
9052 ))
9053 return NULL;
9054
9055 Py_BEGIN_ALLOW_THREADS
9056#ifdef HAVE_FSTATVFS
9057 if (path.fd != -1) {
9058#ifdef __APPLE__
9059 /* handle weak-linking on Mac OS X 10.3 */
9060 if (fstatvfs == NULL) {
9061 fd_specified("statvfs", path.fd);
9062 goto exit;
9063 }
9064#endif
9065 result = fstatvfs(path.fd, &st);
9066 }
9067 else
9068#endif
9069 result = statvfs(path.narrow, &st);
9070 Py_END_ALLOW_THREADS
9071
9072 if (result) {
9073 return_value = path_posix_error("statvfs", &path);
9074 goto exit;
9075 }
9076
9077 return_value = _pystatvfs_fromstructstatvfs(st);
9078
9079exit:
9080 path_cleanup(&path);
9081 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00009082}
9083#endif /* HAVE_STATVFS */
9084
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009085#ifdef MS_WINDOWS
9086PyDoc_STRVAR(win32__getdiskusage__doc__,
9087"_getdiskusage(path) -> (total, free)\n\n\
9088Return disk usage statistics about the given path as (total, free) tuple.");
9089
9090static PyObject *
9091win32__getdiskusage(PyObject *self, PyObject *args)
9092{
9093 BOOL retval;
9094 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01009095 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009096
Victor Stinner6139c1b2011-11-09 22:14:14 +01009097 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009098 return NULL;
9099
9100 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009101 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009102 Py_END_ALLOW_THREADS
9103 if (retval == 0)
9104 return PyErr_SetFromWindowsErr(0);
9105
9106 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9107}
9108#endif
9109
9110
Fred Drakec9680921999-12-13 16:37:25 +00009111/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9112 * It maps strings representing configuration variable names to
9113 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009114 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009115 * rarely-used constants. There are three separate tables that use
9116 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009117 *
9118 * This code is always included, even if none of the interfaces that
9119 * need it are included. The #if hackery needed to avoid it would be
9120 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009121 */
9122struct constdef {
9123 char *name;
9124 long value;
9125};
9126
Fred Drake12c6e2d1999-12-14 21:25:03 +00009127static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009128conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009129 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009130{
Christian Heimes217cfd12007-12-02 14:31:20 +00009131 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009132 *valuep = PyLong_AS_LONG(arg);
9133 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009134 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009135 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009136 /* look up the value in the table using a binary search */
9137 size_t lo = 0;
9138 size_t mid;
9139 size_t hi = tablesize;
9140 int cmp;
9141 const char *confname;
9142 if (!PyUnicode_Check(arg)) {
9143 PyErr_SetString(PyExc_TypeError,
9144 "configuration names must be strings or integers");
9145 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009147 confname = _PyUnicode_AsString(arg);
9148 if (confname == NULL)
9149 return 0;
9150 while (lo < hi) {
9151 mid = (lo + hi) / 2;
9152 cmp = strcmp(confname, table[mid].name);
9153 if (cmp < 0)
9154 hi = mid;
9155 else if (cmp > 0)
9156 lo = mid + 1;
9157 else {
9158 *valuep = table[mid].value;
9159 return 1;
9160 }
9161 }
9162 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9163 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009164 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009165}
9166
9167
9168#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9169static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009170#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009171 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009172#endif
9173#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009175#endif
Fred Drakec9680921999-12-13 16:37:25 +00009176#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009178#endif
9179#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009180 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009181#endif
9182#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009184#endif
9185#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009186 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009187#endif
9188#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009189 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009190#endif
9191#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009193#endif
9194#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009196#endif
9197#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009198 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009199#endif
9200#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009201 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009202#endif
9203#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009204 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009205#endif
9206#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009207 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009208#endif
9209#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009210 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009211#endif
9212#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009213 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009214#endif
9215#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009216 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009217#endif
9218#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009219 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009220#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009221#ifdef _PC_ACL_ENABLED
9222 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9223#endif
9224#ifdef _PC_MIN_HOLE_SIZE
9225 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9226#endif
9227#ifdef _PC_ALLOC_SIZE_MIN
9228 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9229#endif
9230#ifdef _PC_REC_INCR_XFER_SIZE
9231 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9232#endif
9233#ifdef _PC_REC_MAX_XFER_SIZE
9234 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9235#endif
9236#ifdef _PC_REC_MIN_XFER_SIZE
9237 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9238#endif
9239#ifdef _PC_REC_XFER_ALIGN
9240 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9241#endif
9242#ifdef _PC_SYMLINK_MAX
9243 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9244#endif
9245#ifdef _PC_XATTR_ENABLED
9246 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9247#endif
9248#ifdef _PC_XATTR_EXISTS
9249 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9250#endif
9251#ifdef _PC_TIMESTAMP_RESOLUTION
9252 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9253#endif
Fred Drakec9680921999-12-13 16:37:25 +00009254};
9255
Fred Drakec9680921999-12-13 16:37:25 +00009256static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009257conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009258{
9259 return conv_confname(arg, valuep, posix_constants_pathconf,
9260 sizeof(posix_constants_pathconf)
9261 / sizeof(struct constdef));
9262}
9263#endif
9264
9265#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009266PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009267"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009268Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009269If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00009270
9271static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009272posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009273{
9274 PyObject *result = NULL;
9275 int name, fd;
9276
Fred Drake12c6e2d1999-12-14 21:25:03 +00009277 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
9278 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009279 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009280
Stefan Krah0e803b32010-11-26 16:16:47 +00009281 errno = 0;
9282 limit = fpathconf(fd, name);
9283 if (limit == -1 && errno != 0)
9284 posix_error();
9285 else
9286 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009287 }
9288 return result;
9289}
9290#endif
9291
9292
9293#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009294PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009295"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00009296Return the configuration limit name for the file or directory path.\n\
Georg Brandl306336b2012-06-24 12:55:33 +02009297If there is no limit, return -1.\n\
9298On some platforms, path may also be specified as an open file descriptor.\n\
9299 If this functionality is unavailable, using it raises an exception.");
Fred Drakec9680921999-12-13 16:37:25 +00009300
9301static PyObject *
Georg Brandl306336b2012-06-24 12:55:33 +02009302posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
Fred Drakec9680921999-12-13 16:37:25 +00009303{
Georg Brandl306336b2012-06-24 12:55:33 +02009304 path_t path;
Fred Drakec9680921999-12-13 16:37:25 +00009305 PyObject *result = NULL;
9306 int name;
Georg Brandl306336b2012-06-24 12:55:33 +02009307 static char *keywords[] = {"path", "name", NULL};
Fred Drakec9680921999-12-13 16:37:25 +00009308
Georg Brandl306336b2012-06-24 12:55:33 +02009309 memset(&path, 0, sizeof(path));
9310#ifdef HAVE_FPATHCONF
9311 path.allow_fd = 1;
9312#endif
9313 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords,
9314 path_converter, &path,
9315 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009317
Victor Stinner8c62be82010-05-06 00:08:46 +00009318 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009319#ifdef HAVE_FPATHCONF
9320 if (path.fd != -1)
9321 limit = fpathconf(path.fd, name);
9322 else
9323#endif
9324 limit = pathconf(path.narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 if (limit == -1 && errno != 0) {
9326 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009327 /* could be a path or name problem */
9328 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009329 else
Georg Brandl306336b2012-06-24 12:55:33 +02009330 result = path_posix_error("pathconf", &path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 }
9332 else
9333 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00009334 }
Georg Brandl306336b2012-06-24 12:55:33 +02009335 path_cleanup(&path);
Fred Drakec9680921999-12-13 16:37:25 +00009336 return result;
9337}
9338#endif
9339
9340#ifdef HAVE_CONFSTR
9341static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009342#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009344#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009345#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009347#endif
9348#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009350#endif
Fred Draked86ed291999-12-15 15:34:33 +00009351#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009353#endif
9354#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009356#endif
9357#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009359#endif
9360#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009362#endif
Fred Drakec9680921999-12-13 16:37:25 +00009363#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
9369#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009371#endif
9372#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009374#endif
9375#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009376 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009377#endif
9378#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009380#endif
9381#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009383#endif
9384#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009386#endif
Fred Draked86ed291999-12-15 15:34:33 +00009387#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009388 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009389#endif
Fred Drakec9680921999-12-13 16:37:25 +00009390#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009392#endif
Fred Draked86ed291999-12-15 15:34:33 +00009393#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009394 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009395#endif
9396#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009398#endif
9399#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009401#endif
9402#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009404#endif
Fred Drakec9680921999-12-13 16:37:25 +00009405#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009407#endif
9408#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009410#endif
9411#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009413#endif
9414#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009416#endif
9417#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009419#endif
9420#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009422#endif
9423#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009425#endif
9426#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009427 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009428#endif
9429#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009430 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009431#endif
9432#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009434#endif
9435#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009437#endif
9438#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009440#endif
9441#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009443#endif
9444#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009446#endif
9447#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009449#endif
9450#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009452#endif
Fred Draked86ed291999-12-15 15:34:33 +00009453#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009455#endif
9456#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009458#endif
9459#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009461#endif
9462#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009464#endif
9465#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009467#endif
9468#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009470#endif
9471#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009473#endif
9474#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009476#endif
9477#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009479#endif
9480#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009482#endif
9483#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009485#endif
9486#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009488#endif
9489#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009491#endif
Fred Drakec9680921999-12-13 16:37:25 +00009492};
9493
9494static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009495conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009496{
9497 return conv_confname(arg, valuep, posix_constants_confstr,
9498 sizeof(posix_constants_confstr)
9499 / sizeof(struct constdef));
9500}
9501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009502PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009503"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009504Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009505
9506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009507posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009508{
9509 PyObject *result = NULL;
9510 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00009511 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00009512 int len;
Fred Drakec9680921999-12-13 16:37:25 +00009513
Victor Stinnercb043522010-09-10 23:49:04 +00009514 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
9515 return NULL;
9516
9517 errno = 0;
9518 len = confstr(name, buffer, sizeof(buffer));
9519 if (len == 0) {
9520 if (errno) {
9521 posix_error();
9522 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009523 }
9524 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009525 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009526 }
9527 }
Victor Stinnercb043522010-09-10 23:49:04 +00009528
9529 if ((unsigned int)len >= sizeof(buffer)) {
9530 char *buf = PyMem_Malloc(len);
9531 if (buf == NULL)
9532 return PyErr_NoMemory();
9533 confstr(name, buf, len);
9534 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9535 PyMem_Free(buf);
9536 }
9537 else
9538 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009539 return result;
9540}
9541#endif
9542
9543
9544#ifdef HAVE_SYSCONF
9545static struct constdef posix_constants_sysconf[] = {
9546#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
Fred Draked86ed291999-12-15 15:34:33 +00009576#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009578#endif
9579#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009581#endif
Fred Drakec9680921999-12-13 16:37:25 +00009582#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
Fred Drakec9680921999-12-13 16:37:25 +00009585#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
Fred Draked86ed291999-12-15 15:34:33 +00009600#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009602#endif
Fred Drakec9680921999-12-13 16:37:25 +00009603#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009605#endif
9606#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009608#endif
9609#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009611#endif
9612#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009614#endif
9615#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009617#endif
Fred Draked86ed291999-12-15 15:34:33 +00009618#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009620#endif
Fred Drakec9680921999-12-13 16:37:25 +00009621#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009623#endif
9624#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009626#endif
9627#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009629#endif
9630#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009632#endif
9633#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009634 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009635#endif
9636#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009637 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009638#endif
9639#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009640 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009641#endif
9642#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009643 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009644#endif
9645#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009646 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009647#endif
9648#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009649 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009650#endif
9651#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009653#endif
9654#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009655 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009656#endif
9657#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009658 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009659#endif
9660#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009661 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009662#endif
9663#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009664 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009665#endif
9666#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009667 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009668#endif
9669#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009670 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009671#endif
9672#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009674#endif
9675#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009677#endif
9678#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009680#endif
9681#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009683#endif
9684#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009685 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009686#endif
9687#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009689#endif
Fred Draked86ed291999-12-15 15:34:33 +00009690#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009692#endif
Fred Drakec9680921999-12-13 16:37:25 +00009693#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009694 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009695#endif
9696#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009698#endif
9699#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009701#endif
Fred Draked86ed291999-12-15 15:34:33 +00009702#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009704#endif
Fred Drakec9680921999-12-13 16:37:25 +00009705#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009707#endif
Fred Draked86ed291999-12-15 15:34:33 +00009708#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009710#endif
9711#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009713#endif
Fred Drakec9680921999-12-13 16:37:25 +00009714#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009716#endif
9717#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
Fred Draked86ed291999-12-15 15:34:33 +00009726#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009728#endif
Fred Drakec9680921999-12-13 16:37:25 +00009729#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
Fred Draked86ed291999-12-15 15:34:33 +00009750#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009752#endif
Fred Drakec9680921999-12-13 16:37:25 +00009753#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
Fred Draked86ed291999-12-15 15:34:33 +00009759#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009761#endif
Fred Drakec9680921999-12-13 16:37:25 +00009762#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
Fred Draked86ed291999-12-15 15:34:33 +00009789#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009791#endif
9792#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009794#endif
Fred Drakec9680921999-12-13 16:37:25 +00009795#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
9825#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009827#endif
9828#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009830#endif
9831#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009833#endif
9834#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009836#endif
9837#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009839#endif
9840#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009842#endif
9843#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009845#endif
9846#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009848#endif
9849#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009851#endif
9852#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009854#endif
9855#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009857#endif
9858#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009860#endif
9861#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009863#endif
9864#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009865 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009866#endif
9867#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009868 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009869#endif
9870#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009871 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009872#endif
9873#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009874 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009875#endif
9876#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009877 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009878#endif
9879#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009880 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009881#endif
9882#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
Fred Draked86ed291999-12-15 15:34:33 +00009900#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009902#endif
Fred Drakec9680921999-12-13 16:37:25 +00009903#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038};
10039
10040static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010041conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010042{
10043 return conv_confname(arg, valuep, posix_constants_sysconf,
10044 sizeof(posix_constants_sysconf)
10045 / sizeof(struct constdef));
10046}
10047
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010048PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010049"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010050Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +000010051
10052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010053posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +000010054{
10055 PyObject *result = NULL;
10056 int name;
10057
10058 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
10059 int value;
10060
10061 errno = 0;
10062 value = sysconf(name);
10063 if (value == -1 && errno != 0)
10064 posix_error();
10065 else
Christian Heimes217cfd12007-12-02 14:31:20 +000010066 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +000010067 }
10068 return result;
10069}
10070#endif
10071
10072
Fred Drakebec628d1999-12-15 18:31:10 +000010073/* This code is used to ensure that the tables of configuration value names
10074 * are in sorted order as required by conv_confname(), and also to build the
10075 * the exported dictionaries that are used to publish information about the
10076 * names available on the host platform.
10077 *
10078 * Sorting the table at runtime ensures that the table is properly ordered
10079 * when used, even for platforms we're not able to test on. It also makes
10080 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010081 */
Fred Drakebec628d1999-12-15 18:31:10 +000010082
10083static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010084cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010085{
10086 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010088 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010090
10091 return strcmp(c1->name, c2->name);
10092}
10093
10094static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010095setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010097{
Fred Drakebec628d1999-12-15 18:31:10 +000010098 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010099 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010100
10101 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10102 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010103 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010105
Barry Warsaw3155db32000-04-13 15:20:40 +000010106 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 PyObject *o = PyLong_FromLong(table[i].value);
10108 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10109 Py_XDECREF(o);
10110 Py_DECREF(d);
10111 return -1;
10112 }
10113 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010114 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010115 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010116}
10117
Fred Drakebec628d1999-12-15 18:31:10 +000010118/* Return -1 on failure, 0 on success. */
10119static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010120setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010121{
10122#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010123 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010124 sizeof(posix_constants_pathconf)
10125 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010126 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010127 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010128#endif
10129#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010130 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010131 sizeof(posix_constants_confstr)
10132 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010133 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010134 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010135#endif
10136#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010137 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010138 sizeof(posix_constants_sysconf)
10139 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010140 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010141 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010142#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010143 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010144}
Fred Draked86ed291999-12-15 15:34:33 +000010145
10146
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010147PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +000010148"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010149Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010150in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010151
10152static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010153posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010154{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010155 abort();
10156 /*NOTREACHED*/
10157 Py_FatalError("abort() called from Python code didn't abort!");
10158 return NULL;
10159}
Fred Drakebec628d1999-12-15 18:31:10 +000010160
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010161#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010162PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +000010163"startfile(filepath [, operation]) - Start a file with its associated\n\
10164application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010165\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010166When \"operation\" is not specified or \"open\", this acts like\n\
10167double-clicking the file in Explorer, or giving the file name as an\n\
10168argument to the DOS \"start\" command: the file is opened with whatever\n\
10169application (if any) its extension is associated.\n\
10170When another \"operation\" is given, it specifies what should be done with\n\
10171the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010172\n\
10173startfile returns as soon as the associated application is launched.\n\
10174There is no option to wait for the application to close, and no way\n\
10175to retrieve the application's exit status.\n\
10176\n\
10177The filepath is relative to the current directory. If you want to use\n\
10178an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010179the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010180
10181static PyObject *
10182win32_startfile(PyObject *self, PyObject *args)
10183{
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 PyObject *ofilepath;
10185 char *filepath;
10186 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010187 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010189
Victor Stinnereb5657a2011-09-30 01:44:27 +020010190 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 if (!PyArg_ParseTuple(args, "U|s:startfile",
10192 &unipath, &operation)) {
10193 PyErr_Clear();
10194 goto normal;
10195 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010196
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010198 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010200 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 PyErr_Clear();
10202 operation = NULL;
10203 goto normal;
10204 }
10205 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010206
Victor Stinnereb5657a2011-09-30 01:44:27 +020010207 wpath = PyUnicode_AsUnicode(unipath);
10208 if (wpath == NULL)
10209 goto normal;
10210 if (uoperation) {
10211 woperation = PyUnicode_AsUnicode(uoperation);
10212 if (woperation == NULL)
10213 goto normal;
10214 }
10215 else
10216 woperation = NULL;
10217
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +020010219 rc = ShellExecuteW((HWND)0, woperation, wpath,
10220 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 Py_END_ALLOW_THREADS
10222
Victor Stinnereb5657a2011-09-30 01:44:27 +020010223 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010225 win32_error_object("startfile", unipath);
10226 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 }
10228 Py_INCREF(Py_None);
10229 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010230
10231normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10233 PyUnicode_FSConverter, &ofilepath,
10234 &operation))
10235 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010236 if (win32_warn_bytes_api()) {
10237 Py_DECREF(ofilepath);
10238 return NULL;
10239 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 filepath = PyBytes_AsString(ofilepath);
10241 Py_BEGIN_ALLOW_THREADS
10242 rc = ShellExecute((HWND)0, operation, filepath,
10243 NULL, NULL, SW_SHOWNORMAL);
10244 Py_END_ALLOW_THREADS
10245 if (rc <= (HINSTANCE)32) {
10246 PyObject *errval = win32_error("startfile", filepath);
10247 Py_DECREF(ofilepath);
10248 return errval;
10249 }
10250 Py_DECREF(ofilepath);
10251 Py_INCREF(Py_None);
10252 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010253}
10254#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010255
Martin v. Löwis438b5342002-12-27 10:16:42 +000010256#ifdef HAVE_GETLOADAVG
10257PyDoc_STRVAR(posix_getloadavg__doc__,
10258"getloadavg() -> (float, float, float)\n\n\
10259Return the number of processes in the system run queue averaged over\n\
10260the last 1, 5, and 15 minutes or raises OSError if the load average\n\
10261was unobtainable");
10262
10263static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +000010264posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +000010265{
10266 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010267 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010268 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10269 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010270 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010271 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010272}
10273#endif
10274
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010275PyDoc_STRVAR(device_encoding__doc__,
10276"device_encoding(fd) -> str\n\n\
10277Return a string describing the encoding of the device\n\
10278if the output is a terminal; else return None.");
10279
10280static PyObject *
10281device_encoding(PyObject *self, PyObject *args)
10282{
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 int fd;
Brett Cannonefb00c02012-02-29 18:31:31 -050010284
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
10286 return NULL;
Brett Cannonefb00c02012-02-29 18:31:31 -050010287
10288 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010289}
10290
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010291#ifdef HAVE_SETRESUID
10292PyDoc_STRVAR(posix_setresuid__doc__,
10293"setresuid(ruid, euid, suid)\n\n\
10294Set the current process's real, effective, and saved user ids.");
10295
10296static PyObject*
10297posix_setresuid (PyObject *self, PyObject *args)
10298{
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 /* We assume uid_t is no larger than a long. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010300 uid_t ruid, euid, suid;
10301 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
10302 _Py_Uid_Converter, &ruid,
10303 _Py_Uid_Converter, &euid,
10304 _Py_Uid_Converter, &suid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 return NULL;
10306 if (setresuid(ruid, euid, suid) < 0)
10307 return posix_error();
10308 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010309}
10310#endif
10311
10312#ifdef HAVE_SETRESGID
10313PyDoc_STRVAR(posix_setresgid__doc__,
10314"setresgid(rgid, egid, sgid)\n\n\
10315Set the current process's real, effective, and saved group ids.");
10316
10317static PyObject*
10318posix_setresgid (PyObject *self, PyObject *args)
10319{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010320 gid_t rgid, egid, sgid;
10321 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
10322 _Py_Gid_Converter, &rgid,
10323 _Py_Gid_Converter, &egid,
10324 _Py_Gid_Converter, &sgid))
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 return NULL;
10326 if (setresgid(rgid, egid, sgid) < 0)
10327 return posix_error();
10328 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010329}
10330#endif
10331
10332#ifdef HAVE_GETRESUID
10333PyDoc_STRVAR(posix_getresuid__doc__,
10334"getresuid() -> (ruid, euid, suid)\n\n\
10335Get tuple of the current process's real, effective, and saved user ids.");
10336
10337static PyObject*
10338posix_getresuid (PyObject *self, PyObject *noargs)
10339{
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 if (getresuid(&ruid, &euid, &suid) < 0)
10342 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010343 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10344 _PyLong_FromUid(euid),
10345 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010346}
10347#endif
10348
10349#ifdef HAVE_GETRESGID
10350PyDoc_STRVAR(posix_getresgid__doc__,
10351"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +000010352Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010353
10354static PyObject*
10355posix_getresgid (PyObject *self, PyObject *noargs)
10356{
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 uid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 if (getresgid(&rgid, &egid, &sgid) < 0)
10359 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010360 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10361 _PyLong_FromGid(egid),
10362 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010363}
10364#endif
10365
Benjamin Peterson9428d532011-09-14 11:45:52 -040010366#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010367
Benjamin Peterson799bd802011-08-31 22:15:17 -040010368PyDoc_STRVAR(posix_getxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010369"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\
10370Return the value of extended attribute attribute on path.\n\
10371\n\
10372path may be either a string or an open file descriptor.\n\
10373If follow_symlinks is False, and the last element of the path is a symbolic\n\
10374 link, getxattr will examine the symbolic link itself instead of the file\n\
10375 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010376
10377static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010378posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010379{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010380 path_t path;
10381 path_t attribute;
10382 int follow_symlinks = 1;
10383 PyObject *buffer = NULL;
10384 int i;
10385 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010386
Larry Hastings9cf065c2012-06-22 16:30:09 -070010387 memset(&path, 0, sizeof(path));
10388 memset(&attribute, 0, sizeof(attribute));
10389 path.allow_fd = 1;
10390 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
10391 path_converter, &path,
10392 path_converter, &attribute,
10393 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010394 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010395
Larry Hastings9cf065c2012-06-22 16:30:09 -070010396 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks))
10397 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010398
Larry Hastings9cf065c2012-06-22 16:30:09 -070010399 for (i = 0; ; i++) {
10400 void *ptr;
10401 ssize_t result;
10402 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10403 Py_ssize_t buffer_size = buffer_sizes[i];
10404 if (!buffer_size) {
10405 path_error("getxattr", &path);
10406 goto exit;
10407 }
10408 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10409 if (!buffer)
10410 goto exit;
10411 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010412
Larry Hastings9cf065c2012-06-22 16:30:09 -070010413 Py_BEGIN_ALLOW_THREADS;
10414 if (path.fd >= 0)
10415 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size);
10416 else if (follow_symlinks)
10417 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10418 else
10419 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size);
10420 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010421
Larry Hastings9cf065c2012-06-22 16:30:09 -070010422 if (result < 0) {
10423 Py_DECREF(buffer);
10424 buffer = NULL;
10425 if (errno == ERANGE)
10426 continue;
10427 path_error("getxattr", &path);
10428 goto exit;
10429 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010430
Larry Hastings9cf065c2012-06-22 16:30:09 -070010431 if (result != buffer_size) {
10432 /* Can only shrink. */
10433 _PyBytes_Resize(&buffer, result);
10434 }
10435 break;
10436 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010437
Larry Hastings9cf065c2012-06-22 16:30:09 -070010438exit:
10439 path_cleanup(&path);
10440 path_cleanup(&attribute);
10441 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010442}
10443
10444PyDoc_STRVAR(posix_setxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010445"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\
10446Set extended attribute attribute on path to value.\n\
10447path may be either a string or an open file descriptor.\n\
10448If follow_symlinks is False, and the last element of the path is a symbolic\n\
10449 link, setxattr will modify the symbolic link itself instead of the file\n\
10450 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010451
10452static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010453posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010454{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010455 path_t path;
10456 path_t attribute;
10457 Py_buffer value;
10458 int flags = 0;
10459 int follow_symlinks = 1;
10460 int result;
10461 PyObject *return_value = NULL;
10462 static char *keywords[] = {"path", "attribute", "value",
10463 "flags", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010464
Larry Hastings9cf065c2012-06-22 16:30:09 -070010465 memset(&path, 0, sizeof(path));
10466 path.allow_fd = 1;
10467 memset(&attribute, 0, sizeof(attribute));
10468 memset(&value, 0, sizeof(value));
10469 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr",
10470 keywords,
10471 path_converter, &path,
10472 path_converter, &attribute,
10473 &value, &flags,
10474 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010475 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010476
10477 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks))
10478 goto exit;
10479
Benjamin Peterson799bd802011-08-31 22:15:17 -040010480 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010481 if (path.fd > -1)
10482 result = fsetxattr(path.fd, attribute.narrow,
10483 value.buf, value.len, flags);
10484 else if (follow_symlinks)
10485 result = setxattr(path.narrow, attribute.narrow,
10486 value.buf, value.len, flags);
10487 else
10488 result = lsetxattr(path.narrow, attribute.narrow,
10489 value.buf, value.len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010490 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010491
Larry Hastings9cf065c2012-06-22 16:30:09 -070010492 if (result) {
10493 return_value = path_error("setxattr", &path);
10494 goto exit;
10495 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010496
Larry Hastings9cf065c2012-06-22 16:30:09 -070010497 return_value = Py_None;
10498 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010499
Larry Hastings9cf065c2012-06-22 16:30:09 -070010500exit:
10501 path_cleanup(&path);
10502 path_cleanup(&attribute);
10503 PyBuffer_Release(&value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010504
Larry Hastings9cf065c2012-06-22 16:30:09 -070010505 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010506}
10507
10508PyDoc_STRVAR(posix_removexattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010509"removexattr(path, attribute, *, follow_symlinks=True)\n\n\
10510Remove extended attribute attribute on path.\n\
10511path may be either a string or an open file descriptor.\n\
10512If follow_symlinks is False, and the last element of the path is a symbolic\n\
10513 link, removexattr will modify the symbolic link itself instead of the file\n\
10514 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010515
10516static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010517posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010518{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010519 path_t path;
10520 path_t attribute;
10521 int follow_symlinks = 1;
10522 int result;
10523 PyObject *return_value = NULL;
10524 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010525
Larry Hastings9cf065c2012-06-22 16:30:09 -070010526 memset(&path, 0, sizeof(path));
10527 memset(&attribute, 0, sizeof(attribute));
10528 path.allow_fd = 1;
10529 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
10530 keywords,
10531 path_converter, &path,
10532 path_converter, &attribute,
10533 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010534 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010535
10536 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks))
10537 goto exit;
10538
Benjamin Peterson799bd802011-08-31 22:15:17 -040010539 Py_BEGIN_ALLOW_THREADS;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010540 if (path.fd > -1)
10541 result = fremovexattr(path.fd, attribute.narrow);
10542 else if (follow_symlinks)
10543 result = removexattr(path.narrow, attribute.narrow);
10544 else
10545 result = lremovexattr(path.narrow, attribute.narrow);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010546 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010547
Larry Hastings9cf065c2012-06-22 16:30:09 -070010548 if (result) {
10549 return_value = path_error("removexattr", &path);
10550 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010551 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010552
Larry Hastings9cf065c2012-06-22 16:30:09 -070010553 return_value = Py_None;
10554 Py_INCREF(return_value);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010555
Larry Hastings9cf065c2012-06-22 16:30:09 -070010556exit:
10557 path_cleanup(&path);
10558 path_cleanup(&attribute);
10559
10560 return return_value;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010561}
10562
10563PyDoc_STRVAR(posix_listxattr__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -070010564"listxattr(path='.', *, follow_symlinks=True)\n\n\
10565Return a list of extended attributes on path.\n\
10566\n\
10567path may be either None, a string, or an open file descriptor.\n\
10568if path is None, listxattr will examine the current directory.\n\
10569If follow_symlinks is False, and the last element of the path is a symbolic\n\
10570 link, listxattr will examine the symbolic link itself instead of the file\n\
10571 the link points to.");
Benjamin Peterson799bd802011-08-31 22:15:17 -040010572
10573static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -070010574posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Benjamin Peterson799bd802011-08-31 22:15:17 -040010575{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010576 path_t path;
10577 int follow_symlinks = 1;
10578 Py_ssize_t i;
10579 PyObject *result = NULL;
10580 char *buffer = NULL;
10581 char *name;
10582 static char *keywords[] = {"path", "follow_symlinks", NULL};
Benjamin Peterson799bd802011-08-31 22:15:17 -040010583
Larry Hastings9cf065c2012-06-22 16:30:09 -070010584 memset(&path, 0, sizeof(path));
10585 path.allow_fd = 1;
10586 path.fd = -1;
10587 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
10588 path_converter, &path,
10589 &follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010590 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010591
Larry Hastings9cf065c2012-06-22 16:30:09 -070010592 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks))
10593 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010594
Larry Hastings9cf065c2012-06-22 16:30:09 -070010595 name = path.narrow ? path.narrow : ".";
10596 for (i = 0; ; i++) {
10597 char *start, *trace, *end;
10598 ssize_t length;
10599 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10600 Py_ssize_t buffer_size = buffer_sizes[i];
10601 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010602 /* ERANGE */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010603 path_error("listxattr", &path);
10604 break;
10605 }
10606 buffer = PyMem_MALLOC(buffer_size);
10607 if (!buffer) {
10608 PyErr_NoMemory();
10609 break;
10610 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010611
Larry Hastings9cf065c2012-06-22 16:30:09 -070010612 Py_BEGIN_ALLOW_THREADS;
10613 if (path.fd > -1)
10614 length = flistxattr(path.fd, buffer, buffer_size);
10615 else if (follow_symlinks)
10616 length = listxattr(name, buffer, buffer_size);
10617 else
10618 length = llistxattr(name, buffer, buffer_size);
10619 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010620
Larry Hastings9cf065c2012-06-22 16:30:09 -070010621 if (length < 0) {
10622 if (errno == ERANGE)
10623 continue;
10624 path_error("listxattr", &path);
10625 break;
10626 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010627
Larry Hastings9cf065c2012-06-22 16:30:09 -070010628 result = PyList_New(0);
10629 if (!result) {
10630 goto exit;
10631 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010632
Larry Hastings9cf065c2012-06-22 16:30:09 -070010633 end = buffer + length;
10634 for (trace = start = buffer; trace != end; trace++) {
10635 if (!*trace) {
10636 int error;
10637 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10638 trace - start);
10639 if (!attribute) {
10640 Py_DECREF(result);
10641 result = NULL;
10642 goto exit;
10643 }
10644 error = PyList_Append(result, attribute);
10645 Py_DECREF(attribute);
10646 if (error) {
10647 Py_DECREF(result);
10648 result = NULL;
10649 goto exit;
10650 }
10651 start = trace + 1;
10652 }
10653 }
10654 break;
10655 }
10656exit:
10657 path_cleanup(&path);
10658 if (buffer)
10659 PyMem_FREE(buffer);
10660 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010661}
10662
Benjamin Peterson9428d532011-09-14 11:45:52 -040010663#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010664
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010665
Georg Brandl2fb477c2012-02-21 00:33:36 +010010666PyDoc_STRVAR(posix_urandom__doc__,
10667"urandom(n) -> str\n\n\
10668Return n random bytes suitable for cryptographic use.");
10669
10670static PyObject *
10671posix_urandom(PyObject *self, PyObject *args)
10672{
10673 Py_ssize_t size;
10674 PyObject *result;
10675 int ret;
10676
10677 /* Read arguments */
10678 if (!PyArg_ParseTuple(args, "n:urandom", &size))
10679 return NULL;
10680 if (size < 0)
10681 return PyErr_Format(PyExc_ValueError,
10682 "negative argument not allowed");
10683 result = PyBytes_FromStringAndSize(NULL, size);
10684 if (result == NULL)
10685 return NULL;
10686
10687 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
10688 PyBytes_GET_SIZE(result));
10689 if (ret == -1) {
10690 Py_DECREF(result);
10691 return NULL;
10692 }
10693 return result;
10694}
10695
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010696/* Terminal size querying */
10697
10698static PyTypeObject TerminalSizeType;
10699
10700PyDoc_STRVAR(TerminalSize_docstring,
10701 "A tuple of (columns, lines) for holding terminal window size");
10702
10703static PyStructSequence_Field TerminalSize_fields[] = {
10704 {"columns", "width of the terminal window in characters"},
10705 {"lines", "height of the terminal window in characters"},
10706 {NULL, NULL}
10707};
10708
10709static PyStructSequence_Desc TerminalSize_desc = {
10710 "os.terminal_size",
10711 TerminalSize_docstring,
10712 TerminalSize_fields,
10713 2,
10714};
10715
10716#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
10717PyDoc_STRVAR(termsize__doc__,
10718 "Return the size of the terminal window as (columns, lines).\n" \
10719 "\n" \
10720 "The optional argument fd (default standard output) specifies\n" \
10721 "which file descriptor should be queried.\n" \
10722 "\n" \
10723 "If the file descriptor is not connected to a terminal, an OSError\n" \
10724 "is thrown.\n" \
10725 "\n" \
10726 "This function will only be defined if an implementation is\n" \
10727 "available for this system.\n" \
10728 "\n" \
10729 "shutil.get_terminal_size is the high-level function which should \n" \
10730 "normally be used, os.get_terminal_size is the low-level implementation.");
10731
10732static PyObject*
10733get_terminal_size(PyObject *self, PyObject *args)
10734{
10735 int columns, lines;
10736 PyObject *termsize;
10737
10738 int fd = fileno(stdout);
10739 /* Under some conditions stdout may not be connected and
10740 * fileno(stdout) may point to an invalid file descriptor. For example
10741 * GUI apps don't have valid standard streams by default.
10742 *
10743 * If this happens, and the optional fd argument is not present,
10744 * the ioctl below will fail returning EBADF. This is what we want.
10745 */
10746
10747 if (!PyArg_ParseTuple(args, "|i", &fd))
10748 return NULL;
10749
10750#ifdef TERMSIZE_USE_IOCTL
10751 {
10752 struct winsize w;
10753 if (ioctl(fd, TIOCGWINSZ, &w))
10754 return PyErr_SetFromErrno(PyExc_OSError);
10755 columns = w.ws_col;
10756 lines = w.ws_row;
10757 }
10758#endif /* TERMSIZE_USE_IOCTL */
10759
10760#ifdef TERMSIZE_USE_CONIO
10761 {
10762 DWORD nhandle;
10763 HANDLE handle;
10764 CONSOLE_SCREEN_BUFFER_INFO csbi;
10765 switch (fd) {
10766 case 0: nhandle = STD_INPUT_HANDLE;
10767 break;
10768 case 1: nhandle = STD_OUTPUT_HANDLE;
10769 break;
10770 case 2: nhandle = STD_ERROR_HANDLE;
10771 break;
10772 default:
10773 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10774 }
10775 handle = GetStdHandle(nhandle);
10776 if (handle == NULL)
10777 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10778 if (handle == INVALID_HANDLE_VALUE)
10779 return PyErr_SetFromWindowsErr(0);
10780
10781 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10782 return PyErr_SetFromWindowsErr(0);
10783
10784 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10785 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10786 }
10787#endif /* TERMSIZE_USE_CONIO */
10788
10789 termsize = PyStructSequence_New(&TerminalSizeType);
10790 if (termsize == NULL)
10791 return NULL;
10792 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10793 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10794 if (PyErr_Occurred()) {
10795 Py_DECREF(termsize);
10796 return NULL;
10797 }
10798 return termsize;
10799}
10800#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10801
10802
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010803static PyMethodDef posix_methods[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070010804 {"access", (PyCFunction)posix_access,
10805 METH_VARARGS | METH_KEYWORDS,
10806 posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010807#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010809#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010810 {"chdir", (PyCFunction)posix_chdir,
10811 METH_VARARGS | METH_KEYWORDS,
10812 posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010813#ifdef HAVE_CHFLAGS
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814 {"chflags", (PyCFunction)posix_chflags,
10815 METH_VARARGS | METH_KEYWORDS,
10816 posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010817#endif /* HAVE_CHFLAGS */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010818 {"chmod", (PyCFunction)posix_chmod,
10819 METH_VARARGS | METH_KEYWORDS,
10820 posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010821#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010822 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010823#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010824#ifdef HAVE_CHOWN
Larry Hastings9cf065c2012-06-22 16:30:09 -070010825 {"chown", (PyCFunction)posix_chown,
10826 METH_VARARGS | METH_KEYWORDS,
10827 posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010828#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010829#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010831#endif /* HAVE_LCHMOD */
10832#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010834#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010835#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010837#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010838#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010840#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010841#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010842 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010843#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010844#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010845 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010846#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010847#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010848 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10849 METH_NOARGS, posix_getcwd__doc__},
10850 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10851 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010852#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -070010853#if defined(HAVE_LINK) || defined(MS_WINDOWS)
10854 {"link", (PyCFunction)posix_link,
10855 METH_VARARGS | METH_KEYWORDS,
10856 posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010857#endif /* HAVE_LINK */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010858 {"listdir", (PyCFunction)posix_listdir,
10859 METH_VARARGS | METH_KEYWORDS,
10860 posix_listdir__doc__},
10861 {"lstat", (PyCFunction)posix_lstat,
10862 METH_VARARGS | METH_KEYWORDS,
10863 posix_lstat__doc__},
10864 {"mkdir", (PyCFunction)posix_mkdir,
10865 METH_VARARGS | METH_KEYWORDS,
10866 posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010867#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010868 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010869#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010870#ifdef HAVE_GETPRIORITY
10871 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10872#endif /* HAVE_GETPRIORITY */
10873#ifdef HAVE_SETPRIORITY
10874 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10875#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010876#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070010877 {"readlink", (PyCFunction)posix_readlink,
10878 METH_VARARGS | METH_KEYWORDS,
10879 readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010880#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010881#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070010882 {"readlink", (PyCFunction)win_readlink,
10883 METH_VARARGS | METH_KEYWORDS,
10884 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010885#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010886 {"rename", (PyCFunction)posix_rename,
10887 METH_VARARGS | METH_KEYWORDS,
10888 posix_rename__doc__},
10889 {"replace", (PyCFunction)posix_replace,
10890 METH_VARARGS | METH_KEYWORDS,
10891 posix_replace__doc__},
Larry Hastingsb698d8e2012-06-23 16:55:07 -070010892 {"rmdir", (PyCFunction)posix_rmdir,
10893 METH_VARARGS | METH_KEYWORDS,
10894 posix_rmdir__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010895 {"stat", (PyCFunction)posix_stat,
10896 METH_VARARGS | METH_KEYWORDS,
10897 posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010899#if defined(HAVE_SYMLINK)
10900 {"symlink", (PyCFunction)posix_symlink,
10901 METH_VARARGS | METH_KEYWORDS,
10902 posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010903#endif /* HAVE_SYMLINK */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010904#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010905 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010906#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010908#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010910#endif /* HAVE_UNAME */
Larry Hastings9cf065c2012-06-22 16:30:09 -070010911 {"unlink", (PyCFunction)posix_unlink,
10912 METH_VARARGS | METH_KEYWORDS,
10913 posix_unlink__doc__},
10914 {"remove", (PyCFunction)posix_unlink,
10915 METH_VARARGS | METH_KEYWORDS,
10916 posix_remove__doc__},
Larry Hastings76ad59b2012-05-03 00:30:07 -070010917 {"utime", (PyCFunction)posix_utime,
10918 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__},
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010919#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010921#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010922 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010923#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
Larry Hastings9cf065c2012-06-22 16:30:09 -070010925 {"execve", (PyCFunction)posix_execve,
10926 METH_VARARGS | METH_KEYWORDS,
10927 posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010928#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +000010929#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10931 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010932#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10934 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010935#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010936#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010937#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010938 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010939#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010940#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010941 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010942#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010943#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010944#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010945 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10946 {"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 +020010947#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010948#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010949 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010950#endif
10951#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010952 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010953#endif
10954#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010955 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010956#endif
10957#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010958 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010959#endif
10960#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010961 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010962#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010963 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010964#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010965 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10966 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10967#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010968#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010969#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010970 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010971#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010972#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010973 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010974#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010975#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010976 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010977#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010978#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010979 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010980#endif /* HAVE_GETEUID */
10981#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010982 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010983#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010984#ifdef HAVE_GETGROUPLIST
10985 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10986#endif
Fred Drakec9680921999-12-13 16:37:25 +000010987#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010988 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010989#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010990 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010991#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010992 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010993#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010994#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010995 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010996#endif /* HAVE_GETPPID */
10997#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010998 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010999#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000011000#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000011002#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000011003#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000011004 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011005#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011006#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000011007 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000011008#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000011009#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011010 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000011011#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000011012#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011013 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
11014 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000011015#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000011016#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011017 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011018#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011019#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011020 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011021#endif /* HAVE_SETEUID */
11022#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011023 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011024#endif /* HAVE_SETEGID */
11025#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011026 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011027#endif /* HAVE_SETREUID */
11028#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011029 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +000011030#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011031#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011032 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011033#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011034#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011035 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000011036#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000011037#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000011038 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000011039#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000011040#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011041 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000011042#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011043#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011044 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011045#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000011046#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011047 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000011048#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011049#ifdef HAVE_WAIT3
Victor Stinner4195b5c2012-02-08 23:03:19 +010011050 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011051#endif /* HAVE_WAIT3 */
11052#ifdef HAVE_WAIT4
Victor Stinner4195b5c2012-02-08 23:03:19 +010011053 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011054#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020011055#if defined(HAVE_WAITID) && !defined(__APPLE__)
11056 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
11057#endif
Tim Petersab034fa2002-02-01 11:27:43 +000011058#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000011059 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011060#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011061#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011062 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000011063#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011064#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000011065 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011066#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011067#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011068 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011069#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011070#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011071 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011072#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000011073#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000011074 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000011075#endif /* HAVE_TCSETPGRP */
Larry Hastings9cf065c2012-06-22 16:30:09 -070011076 {"open", (PyCFunction)posix_open,\
11077 METH_VARARGS | METH_KEYWORDS,
11078 posix_open__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011079 {"close", posix_close, METH_VARARGS, posix_close__doc__},
11080 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
11081 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
11082 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
11083 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011084#ifdef HAVE_LOCKF
11085 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
11086#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
11088 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011089#ifdef HAVE_READV
11090 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
11091#endif
11092#ifdef HAVE_PREAD
11093 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
11094#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011095 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011096#ifdef HAVE_WRITEV
11097 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
11098#endif
11099#ifdef HAVE_PWRITE
11100 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
11101#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011102#ifdef HAVE_SENDFILE
11103 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
11104 posix_sendfile__doc__},
11105#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +010011106 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011108#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011110#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011111#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020011112 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020011113#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011114#ifdef HAVE_MKFIFO
Larry Hastings9cf065c2012-06-22 16:30:09 -070011115 {"mkfifo", (PyCFunction)posix_mkfifo,
11116 METH_VARARGS | METH_KEYWORDS,
11117 posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011118#endif
Neal Norwitz11690112002-07-30 01:08:28 +000011119#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011120 {"mknod", (PyCFunction)posix_mknod,
11121 METH_VARARGS | METH_KEYWORDS,
11122 posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000011123#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011124#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 {"major", posix_major, METH_VARARGS, posix_major__doc__},
11126 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
11127 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000011128#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011129#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011131#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011132#ifdef HAVE_TRUNCATE
Georg Brandl306336b2012-06-24 12:55:33 +020011133 {"truncate", (PyCFunction)posix_truncate,
11134 METH_VARARGS | METH_KEYWORDS,
11135 posix_truncate__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020011136#endif
11137#ifdef HAVE_POSIX_FALLOCATE
11138 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
11139#endif
11140#ifdef HAVE_POSIX_FADVISE
11141 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
11142#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011143#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011144 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000011145#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000011146#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011147 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000011148#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011150#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000011152#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011153#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011155#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020011156#ifdef HAVE_SYNC
11157 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
11158#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000011159#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000011161#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000011162#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000011163#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000011165#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011166#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000011168#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000011169#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011171#endif /* WIFSTOPPED */
11172#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011174#endif /* WIFSIGNALED */
11175#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011177#endif /* WIFEXITED */
11178#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011180#endif /* WEXITSTATUS */
11181#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011183#endif /* WTERMSIG */
11184#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000011186#endif /* WSTOPSIG */
11187#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011188#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000011189 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011190#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011191#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Larry Hastings9cf065c2012-06-22 16:30:09 -070011192 {"statvfs", (PyCFunction)posix_statvfs,
11193 METH_VARARGS | METH_KEYWORDS,
11194 posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000011195#endif
Fred Drakec9680921999-12-13 16:37:25 +000011196#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000011197 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011198#endif
11199#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011200 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011201#endif
11202#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011204#endif
11205#ifdef HAVE_PATHCONF
Georg Brandl306336b2012-06-24 12:55:33 +020011206 {"pathconf", (PyCFunction)posix_pathconf,
11207 METH_VARARGS | METH_KEYWORDS,
11208 posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000011209#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011210 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000011211#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000011213 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000011214 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050011215 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020011216 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000011217#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000011218#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000011220#endif
Georg Brandl2daf6ae2012-02-20 19:54:16 +010011221 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011222#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011223 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011224#endif
11225#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011226 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011227#endif
11228#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011230#endif
11231#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000011233#endif
11234
Benjamin Peterson9428d532011-09-14 11:45:52 -040011235#ifdef USE_XATTRS
Larry Hastings9cf065c2012-06-22 16:30:09 -070011236 {"setxattr", (PyCFunction)posix_setxattr,
11237 METH_VARARGS | METH_KEYWORDS,
11238 posix_setxattr__doc__},
11239 {"getxattr", (PyCFunction)posix_getxattr,
11240 METH_VARARGS | METH_KEYWORDS,
11241 posix_getxattr__doc__},
11242 {"removexattr", (PyCFunction)posix_removexattr,
11243 METH_VARARGS | METH_KEYWORDS,
11244 posix_removexattr__doc__},
11245 {"listxattr", (PyCFunction)posix_listxattr,
11246 METH_VARARGS | METH_KEYWORDS,
11247 posix_listxattr__doc__},
Benjamin Peterson799bd802011-08-31 22:15:17 -040011248#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011249#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
11250 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
11251#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011252 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011253};
11254
11255
Barry Warsaw4a342091996-12-19 23:50:02 +000011256static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011257ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011258{
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011260}
11261
Guido van Rossumd48f2521997-12-05 22:19:34 +000011262#if defined(PYOS_OS2)
11263/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011264static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011265{
11266 APIRET rc;
11267 ULONG values[QSV_MAX+1];
11268 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011269 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011270
11271 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011272 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011273 Py_END_ALLOW_THREADS
11274
11275 if (rc != NO_ERROR) {
11276 os2_error(rc);
11277 return -1;
11278 }
11279
Fred Drake4d1e64b2002-04-15 19:40:07 +000011280 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11281 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11282 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11283 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11284 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11285 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11286 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011287
11288 switch (values[QSV_VERSION_MINOR]) {
11289 case 0: ver = "2.00"; break;
11290 case 10: ver = "2.10"; break;
11291 case 11: ver = "2.11"; break;
11292 case 30: ver = "3.00"; break;
11293 case 40: ver = "4.00"; break;
11294 case 50: ver = "5.00"; break;
11295 default:
Tim Peters885d4572001-11-28 20:27:42 +000011296 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011298 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011299 ver = &tmp[0];
11300 }
11301
11302 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011303 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011304 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011305
11306 /* Add Indicator of Which Drive was Used to Boot the System */
11307 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11308 tmp[1] = ':';
11309 tmp[2] = '\0';
11310
Fred Drake4d1e64b2002-04-15 19:40:07 +000011311 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011312}
11313#endif
11314
Brian Curtin52173d42010-12-02 18:29:18 +000011315#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011316static int
Brian Curtin52173d42010-12-02 18:29:18 +000011317enable_symlink()
11318{
11319 HANDLE tok;
11320 TOKEN_PRIVILEGES tok_priv;
11321 LUID luid;
11322 int meth_idx = 0;
11323
11324 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011325 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011326
11327 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011328 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011329
11330 tok_priv.PrivilegeCount = 1;
11331 tok_priv.Privileges[0].Luid = luid;
11332 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11333
11334 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11335 sizeof(TOKEN_PRIVILEGES),
11336 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011337 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011338
Brian Curtin3b4499c2010-12-28 14:31:47 +000011339 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11340 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011341}
11342#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11343
Barry Warsaw4a342091996-12-19 23:50:02 +000011344static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011345all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011346{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011347#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011348 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011349#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011350#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011352#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011353#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011354 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011355#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011356#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011357 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011358#endif
Fred Drakec9680921999-12-13 16:37:25 +000011359#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011360 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011361#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011362#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011363 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011364#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011365#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011366 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011367#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011368#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011369 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011370#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011371#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011373#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011374#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011375 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011376#endif
11377#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011378 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011379#endif
11380#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011381 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011382#endif
11383#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011384 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011385#endif
11386#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011387 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011388#endif
11389#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011390 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011391#endif
11392#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011393 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011394#endif
11395#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011396 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011397#endif
11398#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011399 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011400#endif
11401#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011402 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011403#endif
11404#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011405 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011406#endif
11407#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011408 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011409#endif
11410#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011411 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011412#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011413#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011414 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011415#endif
11416#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011417 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011418#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011419#ifdef O_XATTR
11420 if (ins(d, "O_XATTR", (long)O_XATTR)) return -1;
11421#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011422#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011423 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011424#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011425#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011426 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011427#endif
11428#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011429 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011430#endif
Jesus Ceacf381202012-04-24 20:44:40 +020011431#ifdef O_EXEC
11432 if (ins(d, "O_EXEC", (long)O_EXEC)) return -1;
11433#endif
11434#ifdef O_SEARCH
11435 if (ins(d, "O_SEARCH", (long)O_SEARCH)) return -1;
11436#endif
11437#ifdef O_TTY_INIT
11438 if (ins(d, "O_TTY_INIT", (long)O_TTY_INIT)) return -1;
11439#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011440#ifdef PRIO_PROCESS
11441 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11442#endif
11443#ifdef PRIO_PGRP
11444 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11445#endif
11446#ifdef PRIO_USER
11447 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11448#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011449#ifdef O_CLOEXEC
11450 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11451#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011452#ifdef O_ACCMODE
11453 if (ins(d, "O_ACCMODE", (long)O_ACCMODE)) return -1;
11454#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011455
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011456
Jesus Cea94363612012-06-22 18:32:07 +020011457#ifdef SEEK_HOLE
11458 if (ins(d, "SEEK_HOLE", (long)SEEK_HOLE)) return -1;
11459#endif
11460#ifdef SEEK_DATA
11461 if (ins(d, "SEEK_DATA", (long)SEEK_DATA)) return -1;
11462#endif
11463
Tim Peters5aa91602002-01-30 05:46:57 +000011464/* MS Windows */
11465#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011466 /* Don't inherit in child processes. */
11467 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011468#endif
11469#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011470 /* Optimize for short life (keep in memory). */
11471 /* MS forgot to define this one with a non-underscore form too. */
11472 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011473#endif
11474#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011475 /* Automatically delete when last handle is closed. */
11476 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011477#endif
11478#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011479 /* Optimize for random access. */
11480 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011481#endif
11482#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011483 /* Optimize for sequential access. */
11484 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011485#endif
11486
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011487/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011488#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011489 /* Send a SIGIO signal whenever input or output
11490 becomes available on file descriptor */
11491 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011492#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011493#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 /* Direct disk access. */
11495 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011496#endif
11497#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011498 /* Must be a directory. */
11499 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011500#endif
11501#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011502 /* Do not follow links. */
11503 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011504#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020011505#ifdef O_NOLINKS
11506 /* Fails if link count of the named file is greater than 1 */
11507 if (ins(d, "O_NOLINKS", (long)O_NOLINKS)) return -1;
11508#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011509#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011510 /* Do not update the access time. */
11511 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011512#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011513
Victor Stinner8c62be82010-05-06 00:08:46 +000011514 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011515#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011516 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011517#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011518#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011519 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011520#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011521#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011522 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011523#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011524#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011525 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011526#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011527#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011528 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011529#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011530#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011531 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011532#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011533#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011535#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011536#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011537 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011538#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011539#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011540 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011541#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011542#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011544#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011545#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011547#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011548#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011550#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011551#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011552 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011553#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011554#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011555 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011556#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011557#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011559#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011560#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011562#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011563#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011565#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011566
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011567 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011568#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011569 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011570#endif /* ST_RDONLY */
11571#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011572 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011573#endif /* ST_NOSUID */
11574
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011575 /* FreeBSD sendfile() constants */
11576#ifdef SF_NODISKIO
11577 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11578#endif
11579#ifdef SF_MNOWAIT
11580 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11581#endif
11582#ifdef SF_SYNC
11583 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11584#endif
11585
Ross Lagerwall7807c352011-03-17 20:20:30 +020011586 /* constants for posix_fadvise */
11587#ifdef POSIX_FADV_NORMAL
11588 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11589#endif
11590#ifdef POSIX_FADV_SEQUENTIAL
11591 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11592#endif
11593#ifdef POSIX_FADV_RANDOM
11594 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11595#endif
11596#ifdef POSIX_FADV_NOREUSE
11597 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11598#endif
11599#ifdef POSIX_FADV_WILLNEED
11600 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11601#endif
11602#ifdef POSIX_FADV_DONTNEED
11603 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11604#endif
11605
11606 /* constants for waitid */
11607#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11608 if (ins(d, "P_PID", (long)P_PID)) return -1;
11609 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11610 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11611#endif
11612#ifdef WEXITED
11613 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11614#endif
11615#ifdef WNOWAIT
11616 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11617#endif
11618#ifdef WSTOPPED
11619 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11620#endif
11621#ifdef CLD_EXITED
11622 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11623#endif
11624#ifdef CLD_DUMPED
11625 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11626#endif
11627#ifdef CLD_TRAPPED
11628 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11629#endif
11630#ifdef CLD_CONTINUED
11631 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11632#endif
11633
11634 /* constants for lockf */
11635#ifdef F_LOCK
11636 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11637#endif
11638#ifdef F_TLOCK
11639 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11640#endif
11641#ifdef F_ULOCK
11642 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11643#endif
11644#ifdef F_TEST
11645 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11646#endif
11647
Guido van Rossum246bc171999-02-01 23:54:31 +000011648#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011649#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011650 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11651 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11652 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11653 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11654 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11655 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11656 if (ins(d, "P_PM", (long)P_PM)) return -1;
11657 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11658 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11659 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11660 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11661 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11662 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11663 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11664 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11665 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11666 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11667 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11668 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11669 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011670#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011671 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11672 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11673 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11674 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11675 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011676#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011677#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011678
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011679#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011680 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011681 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11682 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11683#ifdef SCHED_SPORADIC
11684 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11685#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011686#ifdef SCHED_BATCH
11687 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11688#endif
11689#ifdef SCHED_IDLE
11690 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11691#endif
11692#ifdef SCHED_RESET_ON_FORK
11693 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11694#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011695#ifdef SCHED_SYS
11696 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11697#endif
11698#ifdef SCHED_IA
11699 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11700#endif
11701#ifdef SCHED_FSS
11702 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11703#endif
11704#ifdef SCHED_FX
11705 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11706#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011707#endif
11708
Benjamin Peterson9428d532011-09-14 11:45:52 -040011709#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011710 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11711 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11712 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11713#endif
11714
Victor Stinner8b905bd2011-10-25 13:34:04 +020011715#ifdef RTLD_LAZY
11716 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11717#endif
11718#ifdef RTLD_NOW
11719 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11720#endif
11721#ifdef RTLD_GLOBAL
11722 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11723#endif
11724#ifdef RTLD_LOCAL
11725 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11726#endif
11727#ifdef RTLD_NODELETE
11728 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11729#endif
11730#ifdef RTLD_NOLOAD
11731 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11732#endif
11733#ifdef RTLD_DEEPBIND
11734 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11735#endif
11736
Guido van Rossumd48f2521997-12-05 22:19:34 +000011737#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011738 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011739#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011740 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011741}
11742
11743
Tim Peters5aa91602002-01-30 05:46:57 +000011744#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011745#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011746#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011747
11748#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011749#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011750#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011751
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011752#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011753#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011754#define MODNAME "posix"
11755#endif
11756
Martin v. Löwis1a214512008-06-11 05:26:20 +000011757static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011758 PyModuleDef_HEAD_INIT,
11759 MODNAME,
11760 posix__doc__,
11761 -1,
11762 posix_methods,
11763 NULL,
11764 NULL,
11765 NULL,
11766 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011767};
11768
11769
Larry Hastings9cf065c2012-06-22 16:30:09 -070011770static char *have_functions[] = {
11771
11772#ifdef HAVE_FACCESSAT
11773 "HAVE_FACCESSAT",
11774#endif
11775
11776#ifdef HAVE_FCHDIR
11777 "HAVE_FCHDIR",
11778#endif
11779
11780#ifdef HAVE_FCHMOD
11781 "HAVE_FCHMOD",
11782#endif
11783
11784#ifdef HAVE_FCHMODAT
11785 "HAVE_FCHMODAT",
11786#endif
11787
11788#ifdef HAVE_FCHOWN
11789 "HAVE_FCHOWN",
11790#endif
11791
11792#ifdef HAVE_FEXECVE
11793 "HAVE_FEXECVE",
11794#endif
11795
11796#ifdef HAVE_FDOPENDIR
11797 "HAVE_FDOPENDIR",
11798#endif
11799
Georg Brandl306336b2012-06-24 12:55:33 +020011800#ifdef HAVE_FPATHCONF
11801 "HAVE_FPATHCONF",
11802#endif
11803
Larry Hastings9cf065c2012-06-22 16:30:09 -070011804#ifdef HAVE_FSTATAT
11805 "HAVE_FSTATAT",
11806#endif
11807
11808#ifdef HAVE_FSTATVFS
11809 "HAVE_FSTATVFS",
11810#endif
11811
Georg Brandl306336b2012-06-24 12:55:33 +020011812#ifdef HAVE_FTRUNCATE
11813 "HAVE_FTRUNCATE",
11814#endif
11815
Larry Hastings9cf065c2012-06-22 16:30:09 -070011816#ifdef HAVE_FUTIMENS
11817 "HAVE_FUTIMENS",
11818#endif
11819
11820#ifdef HAVE_FUTIMES
11821 "HAVE_FUTIMES",
11822#endif
11823
11824#ifdef HAVE_FUTIMESAT
11825 "HAVE_FUTIMESAT",
11826#endif
11827
11828#ifdef HAVE_LINKAT
11829 "HAVE_LINKAT",
11830#endif
11831
11832#ifdef HAVE_LCHFLAGS
11833 "HAVE_LCHFLAGS",
11834#endif
11835
11836#ifdef HAVE_LCHMOD
11837 "HAVE_LCHMOD",
11838#endif
11839
11840#ifdef HAVE_LCHOWN
11841 "HAVE_LCHOWN",
11842#endif
11843
11844#ifdef HAVE_LSTAT
11845 "HAVE_LSTAT",
11846#endif
11847
11848#ifdef HAVE_LUTIMES
11849 "HAVE_LUTIMES",
11850#endif
11851
11852#ifdef HAVE_MKDIRAT
11853 "HAVE_MKDIRAT",
11854#endif
11855
11856#ifdef HAVE_MKFIFOAT
11857 "HAVE_MKFIFOAT",
11858#endif
11859
11860#ifdef HAVE_MKNODAT
11861 "HAVE_MKNODAT",
11862#endif
11863
11864#ifdef HAVE_OPENAT
11865 "HAVE_OPENAT",
11866#endif
11867
11868#ifdef HAVE_READLINKAT
11869 "HAVE_READLINKAT",
11870#endif
11871
11872#ifdef HAVE_RENAMEAT
11873 "HAVE_RENAMEAT",
11874#endif
11875
11876#ifdef HAVE_SYMLINKAT
11877 "HAVE_SYMLINKAT",
11878#endif
11879
11880#ifdef HAVE_UNLINKAT
11881 "HAVE_UNLINKAT",
11882#endif
11883
11884#ifdef HAVE_UTIMENSAT
11885 "HAVE_UTIMENSAT",
11886#endif
11887
11888#ifdef MS_WINDOWS
11889 "MS_WINDOWS",
11890#endif
11891
11892 NULL
11893};
11894
11895
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011896PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011897INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011898{
Victor Stinner8c62be82010-05-06 00:08:46 +000011899 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011900 PyObject *list;
11901 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000011902
Brian Curtin52173d42010-12-02 18:29:18 +000011903#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011904 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011905#endif
11906
Victor Stinner8c62be82010-05-06 00:08:46 +000011907 m = PyModule_Create(&posixmodule);
11908 if (m == NULL)
11909 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011910
Victor Stinner8c62be82010-05-06 00:08:46 +000011911 /* Initialize environ dictionary */
11912 v = convertenviron();
11913 Py_XINCREF(v);
11914 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11915 return NULL;
11916 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011917
Victor Stinner8c62be82010-05-06 00:08:46 +000011918 if (all_ins(m))
11919 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011920
Victor Stinner8c62be82010-05-06 00:08:46 +000011921 if (setup_confname_tables(m))
11922 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011923
Victor Stinner8c62be82010-05-06 00:08:46 +000011924 Py_INCREF(PyExc_OSError);
11925 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011926
Guido van Rossumb3d39562000-01-31 18:41:26 +000011927#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011928 if (posix_putenv_garbage == NULL)
11929 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011930#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011931
Victor Stinner8c62be82010-05-06 00:08:46 +000011932 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011933#if defined(HAVE_WAITID) && !defined(__APPLE__)
11934 waitid_result_desc.name = MODNAME ".waitid_result";
11935 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11936#endif
11937
Victor Stinner8c62be82010-05-06 00:08:46 +000011938 stat_result_desc.name = MODNAME ".stat_result";
11939 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11940 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11941 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11942 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11943 structseq_new = StatResultType.tp_new;
11944 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011945
Victor Stinner8c62be82010-05-06 00:08:46 +000011946 statvfs_result_desc.name = MODNAME ".statvfs_result";
11947 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011948#ifdef NEED_TICKS_PER_SECOND
11949# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011950 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011951# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011952 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011953# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011954 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011955# endif
11956#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011957
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011958#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011959 sched_param_desc.name = MODNAME ".sched_param";
11960 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11961 SchedParamType.tp_new = sched_param_new;
11962#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011963
11964 /* initialize TerminalSize_info */
11965 PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc);
Victor Stinner8c62be82010-05-06 00:08:46 +000011966 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011967#if defined(HAVE_WAITID) && !defined(__APPLE__)
11968 Py_INCREF((PyObject*) &WaitidResultType);
11969 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11970#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011971 Py_INCREF((PyObject*) &StatResultType);
11972 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11973 Py_INCREF((PyObject*) &StatVFSResultType);
11974 PyModule_AddObject(m, "statvfs_result",
11975 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011976
11977#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011978 Py_INCREF(&SchedParamType);
11979 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011980#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000011981
Larry Hastings605a62d2012-06-24 04:33:36 -070011982 times_result_desc.name = MODNAME ".times_result";
11983 PyStructSequence_InitType(&TimesResultType, &times_result_desc);
11984 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
11985
11986 uname_result_desc.name = MODNAME ".uname_result";
11987 PyStructSequence_InitType(&UnameResultType, &uname_result_desc);
11988 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
11989
Thomas Wouters477c8d52006-05-27 19:21:47 +000011990#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011991 /*
11992 * Step 2 of weak-linking support on Mac OS X.
11993 *
11994 * The code below removes functions that are not available on the
11995 * currently active platform.
11996 *
11997 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070011998 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000011999 * OSX 10.4.
12000 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012001#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012002 if (fstatvfs == NULL) {
12003 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12004 return NULL;
12005 }
12006 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012007#endif /* HAVE_FSTATVFS */
12008
12009#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012010 if (statvfs == NULL) {
12011 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12012 return NULL;
12013 }
12014 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012015#endif /* HAVE_STATVFS */
12016
12017# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012018 if (lchown == NULL) {
12019 if (PyObject_DelAttrString(m, "lchown") == -1) {
12020 return NULL;
12021 }
12022 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012023#endif /* HAVE_LCHOWN */
12024
12025
12026#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012027
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020012028 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012029 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
12030
Larry Hastings6fe20b32012-04-19 15:07:49 -070012031 billion = PyLong_FromLong(1000000000);
12032 if (!billion)
12033 return NULL;
12034
Larry Hastings9cf065c2012-06-22 16:30:09 -070012035 /* suppress "function not used" warnings */
12036 {
12037 int ignored;
12038 fd_specified("", -1);
12039 follow_symlinks_specified("", 1);
12040 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
12041 dir_fd_converter(Py_None, &ignored);
12042 dir_fd_unavailable(Py_None, &ignored);
12043 }
12044
12045 /*
12046 * provide list of locally available functions
12047 * so os.py can populate support_* lists
12048 */
12049 list = PyList_New(0);
12050 if (!list)
12051 return NULL;
12052 for (trace = have_functions; *trace; trace++) {
12053 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
12054 if (!unicode)
12055 return NULL;
12056 if (PyList_Append(list, unicode))
12057 return NULL;
12058 Py_DECREF(unicode);
12059 }
12060 PyModule_AddObject(m, "_have_functions", list);
12061
12062 initialized = 1;
12063
Victor Stinner8c62be82010-05-06 00:08:46 +000012064 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000012065
Guido van Rossumb6775db1994-08-01 11:34:53 +000012066}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012067
12068#ifdef __cplusplus
12069}
12070#endif