blob: 14ef71045c45a62ae4d748f2004aa98118c1eb8e [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"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson9428d532011-09-14 11:45:52 -0400110#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
111#define USE_XATTRS
112#endif
113
114#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400115#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400116#endif
117
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
119#ifdef HAVE_SYS_SOCKET_H
120#include <sys/socket.h>
121#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#endif
123
Victor Stinner8b905bd2011-10-25 13:34:04 +0200124#ifdef HAVE_DLFCN_H
125#include <dlfcn.h>
126#endif
127
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000129/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000131#include <process.h>
132#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#define HAVE_GETCWD 1
135#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#if defined(__OS2__)
138#define HAVE_EXECV 1
139#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#include <process.h>
142#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000143#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#define HAVE_EXECV 1
145#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_WAIT 1
150#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000152#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000153#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000154#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#define HAVE_EXECV 1
157#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#define HAVE_SYSTEM 1
159#define HAVE_CWAIT 1
160#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000161#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000162#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000163#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
164/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166/* Unix functions that the configure script doesn't check for */
167#define HAVE_EXECV 1
168#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000170#define HAVE_FORK1 1
171#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_GETCWD 1
173#define HAVE_GETEGID 1
174#define HAVE_GETEUID 1
175#define HAVE_GETGID 1
176#define HAVE_GETPPID 1
177#define HAVE_GETUID 1
178#define HAVE_KILL 1
179#define HAVE_OPENDIR 1
180#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000183#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000184#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#endif /* _MSC_VER */
186#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000187#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000189
Victor Stinnera2f7c002012-02-08 03:36:25 +0100190
191
192
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000193#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000194
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000195#if defined(__sgi)&&_COMPILER_VERSION>=700
196/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
197 (default) */
198extern char *ctermid_r(char *);
199#endif
200
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000201#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000205#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#endif
211#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chdir(char *);
213extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000214#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int chdir(const char *);
216extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000217#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000218#ifdef __BORLANDC__
219extern int chmod(const char *, int);
220#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000222#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000223/*#ifdef HAVE_FCHMOD
224extern int fchmod(int, mode_t);
225#endif*/
226/*#ifdef HAVE_LCHMOD
227extern int lchmod(const char *, mode_t);
228#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int chown(const char *, uid_t, gid_t);
230extern char *getcwd(char *, int);
231extern char *strerror(int);
232extern int link(const char *, const char *);
233extern int rename(const char *, const char *);
234extern int stat(const char *, struct stat *);
235extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000238#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000241#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000243
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#ifdef HAVE_UTIME_H
247#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000248#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000250#ifdef HAVE_SYS_UTIME_H
251#include <sys/utime.h>
252#define HAVE_UTIME_H /* pretend we do for the rest of this file */
253#endif /* HAVE_SYS_UTIME_H */
254
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_SYS_TIMES_H
256#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_PARAM_H
260#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
263#ifdef HAVE_SYS_UTSNAME_H
264#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000265#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000267#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000271#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000272#include <direct.h>
273#define NAMLEN(dirent) strlen((dirent)->d_name)
274#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#endif
281#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#endif
284#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#endif
287#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000289#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#endif
293#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#endif
296#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000297#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000299#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000300#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#endif
302#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
305#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000306#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000307#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000309#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000311#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000312#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000313#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
314#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000315static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000316#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318
Guido van Rossumd48f2521997-12-05 22:19:34 +0000319#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000320#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000321#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#if defined(PATH_MAX) && PATH_MAX > 1024
325#define MAXPATHLEN PATH_MAX
326#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#endif /* MAXPATHLEN */
330
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000331#ifdef UNION_WAIT
332/* Emulate some macros on systems that have a union instead of macros */
333
334#ifndef WIFEXITED
335#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
336#endif
337
338#ifndef WEXITSTATUS
339#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
340#endif
341
342#ifndef WTERMSIG
343#define WTERMSIG(u_wait) ((u_wait).w_termsig)
344#endif
345
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000346#define WAIT_TYPE union wait
347#define WAIT_STATUS_INT(s) (s.w_status)
348
349#else /* !UNION_WAIT */
350#define WAIT_TYPE int
351#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000352#endif /* UNION_WAIT */
353
Greg Wardb48bc172000-03-01 21:51:56 +0000354/* Don't use the "_r" form if we don't need it (also, won't have a
355 prototype for it, at least on Solaris -- maybe others as well?). */
356#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
357#define USE_CTERMID_R
358#endif
359
Fred Drake699f3522000-06-29 21:12:41 +0000360/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000361#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000362#undef FSTAT
363#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000364#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define STAT win32_stat
366# define FSTAT win32_fstat
367# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000368#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define STAT stat
370# define FSTAT fstat
371# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000372#endif
373
Tim Peters11b23062003-04-23 02:39:17 +0000374#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000375#include <sys/mkdev.h>
376#else
377#if defined(MAJOR_IN_SYSMACROS)
378#include <sys/sysmacros.h>
379#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000380#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
381#include <sys/mkdev.h>
382#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000383#endif
Fred Drake699f3522000-06-29 21:12:41 +0000384
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200385/* A helper used by a number of POSIX-only functions */
386#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000387static int
388_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000389{
390#if !defined(HAVE_LARGEFILE_SUPPORT)
391 *((off_t*)addr) = PyLong_AsLong(arg);
392#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000393 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000394#endif
395 if (PyErr_Occurred())
396 return 0;
397 return 1;
398}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200399#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000400
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000401#if defined _MSC_VER && _MSC_VER >= 1400
402/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
403 * valid and throw an assertion if it isn't.
404 * Normally, an invalid fd is likely to be a C program error and therefore
405 * an assertion can be useful, but it does contradict the POSIX standard
406 * which for write(2) states:
407 * "Otherwise, -1 shall be returned and errno set to indicate the error."
408 * "[EBADF] The fildes argument is not a valid file descriptor open for
409 * writing."
410 * Furthermore, python allows the user to enter any old integer
411 * as a fd and should merely raise a python exception on error.
412 * The Microsoft CRT doesn't provide an official way to check for the
413 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000414 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000415 * internal structures involved.
416 * The structures below must be updated for each version of visual studio
417 * according to the file internal.h in the CRT source, until MS comes
418 * up with a less hacky way to do this.
419 * (all of this is to avoid globally modifying the CRT behaviour using
420 * _set_invalid_parameter_handler() and _CrtSetReportMode())
421 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000422/* The actual size of the structure is determined at runtime.
423 * Only the first items must be present.
424 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000425typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000426 intptr_t osfhnd;
427 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000428} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000429
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000430extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000431#define IOINFO_L2E 5
432#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
433#define IOINFO_ARRAYS 64
434#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
435#define FOPEN 0x01
436#define _NO_CONSOLE_FILENO (intptr_t)-2
437
438/* This function emulates what the windows CRT does to validate file handles */
439int
440_PyVerify_fd(int fd)
441{
Victor Stinner8c62be82010-05-06 00:08:46 +0000442 const int i1 = fd >> IOINFO_L2E;
443 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000444
Antoine Pitrou22e41552010-08-15 18:07:50 +0000445 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000446
Victor Stinner8c62be82010-05-06 00:08:46 +0000447 /* Determine the actual size of the ioinfo structure,
448 * as used by the CRT loaded in memory
449 */
450 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
451 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
452 }
453 if (sizeof_ioinfo == 0) {
454 /* This should not happen... */
455 goto fail;
456 }
457
458 /* See that it isn't a special CLEAR fileno */
459 if (fd != _NO_CONSOLE_FILENO) {
460 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
461 * we check pointer validity and other info
462 */
463 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
464 /* finally, check that the file is open */
465 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
466 if (info->osfile & FOPEN) {
467 return 1;
468 }
469 }
470 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000471 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000472 errno = EBADF;
473 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000474}
475
476/* the special case of checking dup2. The target fd must be in a sensible range */
477static int
478_PyVerify_fd_dup2(int fd1, int fd2)
479{
Victor Stinner8c62be82010-05-06 00:08:46 +0000480 if (!_PyVerify_fd(fd1))
481 return 0;
482 if (fd2 == _NO_CONSOLE_FILENO)
483 return 0;
484 if ((unsigned)fd2 < _NHANDLE_)
485 return 1;
486 else
487 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000488}
489#else
490/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
491#define _PyVerify_fd_dup2(A, B) (1)
492#endif
493
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000494#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000495/* The following structure was copied from
496 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
497 include doesn't seem to be present in the Windows SDK (at least as included
498 with Visual Studio Express). */
499typedef struct _REPARSE_DATA_BUFFER {
500 ULONG ReparseTag;
501 USHORT ReparseDataLength;
502 USHORT Reserved;
503 union {
504 struct {
505 USHORT SubstituteNameOffset;
506 USHORT SubstituteNameLength;
507 USHORT PrintNameOffset;
508 USHORT PrintNameLength;
509 ULONG Flags;
510 WCHAR PathBuffer[1];
511 } SymbolicLinkReparseBuffer;
512
513 struct {
514 USHORT SubstituteNameOffset;
515 USHORT SubstituteNameLength;
516 USHORT PrintNameOffset;
517 USHORT PrintNameLength;
518 WCHAR PathBuffer[1];
519 } MountPointReparseBuffer;
520
521 struct {
522 UCHAR DataBuffer[1];
523 } GenericReparseBuffer;
524 };
525} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
526
527#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
528 GenericReparseBuffer)
529#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
530
531static int
Brian Curtind25aef52011-06-13 15:16:04 -0500532win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000533{
534 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
535 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
536 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000537
538 if (0 == DeviceIoControl(
539 reparse_point_handle,
540 FSCTL_GET_REPARSE_POINT,
541 NULL, 0, /* in buffer */
542 target_buffer, sizeof(target_buffer),
543 &n_bytes_returned,
544 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500545 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000546
547 if (reparse_tag)
548 *reparse_tag = rdb->ReparseTag;
549
Brian Curtind25aef52011-06-13 15:16:04 -0500550 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000551}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100552
553static int
554win32_warn_bytes_api()
555{
556 return PyErr_WarnEx(PyExc_DeprecationWarning,
557 "The Windows bytes API has been deprecated, "
558 "use Unicode filenames instead",
559 1);
560}
561
562static PyObject*
563win32_decode_filename(PyObject *obj)
564{
565 PyObject *unicode;
566 if (PyUnicode_Check(obj)) {
567 if (PyUnicode_READY(obj))
568 return NULL;
569 Py_INCREF(obj);
570 return obj;
571 }
572 if (!PyUnicode_FSDecoder(obj, &unicode))
573 return NULL;
574 if (win32_warn_bytes_api()) {
575 Py_DECREF(unicode);
576 return NULL;
577 }
578 return unicode;
579}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000580#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000581
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000582/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000583#ifdef WITH_NEXT_FRAMEWORK
584/* On Darwin/MacOSX a shared library or framework has no access to
585** environ directly, we must obtain it with _NSGetEnviron().
586*/
587#include <crt_externs.h>
588static char **environ;
589#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000590extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000591#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000592
Barry Warsaw53699e91996-12-10 23:23:01 +0000593static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000594convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595{
Victor Stinner8c62be82010-05-06 00:08:46 +0000596 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000597#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000598 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000599#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000600 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000601#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000602#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000603 APIRET rc;
604 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
605#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000606
Victor Stinner8c62be82010-05-06 00:08:46 +0000607 d = PyDict_New();
608 if (d == NULL)
609 return NULL;
610#ifdef WITH_NEXT_FRAMEWORK
611 if (environ == NULL)
612 environ = *_NSGetEnviron();
613#endif
614#ifdef MS_WINDOWS
615 /* _wenviron must be initialized in this way if the program is started
616 through main() instead of wmain(). */
617 _wgetenv(L"");
618 if (_wenviron == NULL)
619 return d;
620 /* This part ignores errors */
621 for (e = _wenviron; *e != NULL; e++) {
622 PyObject *k;
623 PyObject *v;
624 wchar_t *p = wcschr(*e, L'=');
625 if (p == NULL)
626 continue;
627 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
628 if (k == NULL) {
629 PyErr_Clear();
630 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000631 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000632 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
633 if (v == NULL) {
634 PyErr_Clear();
635 Py_DECREF(k);
636 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000637 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000638 if (PyDict_GetItem(d, k) == NULL) {
639 if (PyDict_SetItem(d, k, v) != 0)
640 PyErr_Clear();
641 }
642 Py_DECREF(k);
643 Py_DECREF(v);
644 }
645#else
646 if (environ == NULL)
647 return d;
648 /* This part ignores errors */
649 for (e = environ; *e != NULL; e++) {
650 PyObject *k;
651 PyObject *v;
652 char *p = strchr(*e, '=');
653 if (p == NULL)
654 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000655 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000656 if (k == NULL) {
657 PyErr_Clear();
658 continue;
659 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000660 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000661 if (v == NULL) {
662 PyErr_Clear();
663 Py_DECREF(k);
664 continue;
665 }
666 if (PyDict_GetItem(d, k) == NULL) {
667 if (PyDict_SetItem(d, k, v) != 0)
668 PyErr_Clear();
669 }
670 Py_DECREF(k);
671 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000672 }
673#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000674#if defined(PYOS_OS2)
675 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
676 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
677 PyObject *v = PyBytes_FromString(buffer);
678 PyDict_SetItemString(d, "BEGINLIBPATH", v);
679 Py_DECREF(v);
680 }
681 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
682 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
683 PyObject *v = PyBytes_FromString(buffer);
684 PyDict_SetItemString(d, "ENDLIBPATH", v);
685 Py_DECREF(v);
686 }
687#endif
688 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000689}
690
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691/* Set a POSIX-specific error from errno, and return NULL */
692
Barry Warsawd58d7641998-07-23 16:14:40 +0000693static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000694posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000695{
Victor Stinner8c62be82010-05-06 00:08:46 +0000696 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000697}
Barry Warsawd58d7641998-07-23 16:14:40 +0000698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000699posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000700{
Victor Stinner8c62be82010-05-06 00:08:46 +0000701 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000702}
703
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000704
Mark Hammondef8b6542001-05-13 08:04:26 +0000705static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000706posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000707{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000708 PyObject *name_str, *rc;
709 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
710 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000711 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000712 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
713 name_str);
714 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000715 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000716}
717
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000718#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000719static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000720win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000721{
Victor Stinner8c62be82010-05-06 00:08:46 +0000722 /* XXX We should pass the function name along in the future.
723 (winreg.c also wants to pass the function name.)
724 This would however require an additional param to the
725 Windows error object, which is non-trivial.
726 */
727 errno = GetLastError();
728 if (filename)
729 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
730 else
731 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000732}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000733
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000734static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +0200735win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000736{
Victor Stinner8c62be82010-05-06 00:08:46 +0000737 /* XXX - see win32_error for comments on 'function' */
738 errno = GetLastError();
739 if (filename)
740 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
741 else
742 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000743}
744
Victor Stinnereb5657a2011-09-30 01:44:27 +0200745static PyObject *
746win32_error_object(char* function, PyObject* filename)
747{
748 /* XXX - see win32_error for comments on 'function' */
749 errno = GetLastError();
750 if (filename)
751 return PyErr_SetExcFromWindowsErrWithFilenameObject(
752 PyExc_WindowsError,
753 errno,
754 filename);
755 else
756 return PyErr_SetFromWindowsErr(errno);
757}
758
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000759#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000760
Guido van Rossumd48f2521997-12-05 22:19:34 +0000761#if defined(PYOS_OS2)
762/**********************************************************************
763 * Helper Function to Trim and Format OS/2 Messages
764 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000765static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000766os2_formatmsg(char *msgbuf, int msglen, char *reason)
767{
768 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
769
770 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
771 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
772
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000773 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000774 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
775 }
776
777 /* Add Optional Reason Text */
778 if (reason) {
779 strcat(msgbuf, " : ");
780 strcat(msgbuf, reason);
781 }
782}
783
784/**********************************************************************
785 * Decode an OS/2 Operating System Error Code
786 *
787 * A convenience function to lookup an OS/2 error code and return a
788 * text message we can use to raise a Python exception.
789 *
790 * Notes:
791 * The messages for errors returned from the OS/2 kernel reside in
792 * the file OSO001.MSG in the \OS2 directory hierarchy.
793 *
794 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000795static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000796os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
797{
798 APIRET rc;
799 ULONG msglen;
800
801 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
802 Py_BEGIN_ALLOW_THREADS
803 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
804 errorcode, "oso001.msg", &msglen);
805 Py_END_ALLOW_THREADS
806
807 if (rc == NO_ERROR)
808 os2_formatmsg(msgbuf, msglen, reason);
809 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000810 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000811 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000812
813 return msgbuf;
814}
815
816/* Set an OS/2-specific error and return NULL. OS/2 kernel
817 errors are not in a global variable e.g. 'errno' nor are
818 they congruent with posix error numbers. */
819
Victor Stinner8c62be82010-05-06 00:08:46 +0000820static PyObject *
821os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000822{
823 char text[1024];
824 PyObject *v;
825
826 os2_strerror(text, sizeof(text), code, "");
827
828 v = Py_BuildValue("(is)", code, text);
829 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000830 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000831 Py_DECREF(v);
832 }
833 return NULL; /* Signal to Python that an Exception is Pending */
834}
835
836#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000837
838/* POSIX generic methods */
839
Barry Warsaw53699e91996-12-10 23:23:01 +0000840static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000841posix_fildes(PyObject *fdobj, int (*func)(int))
842{
Victor Stinner8c62be82010-05-06 00:08:46 +0000843 int fd;
844 int res;
845 fd = PyObject_AsFileDescriptor(fdobj);
846 if (fd < 0)
847 return NULL;
848 if (!_PyVerify_fd(fd))
849 return posix_error();
850 Py_BEGIN_ALLOW_THREADS
851 res = (*func)(fd);
852 Py_END_ALLOW_THREADS
853 if (res < 0)
854 return posix_error();
855 Py_INCREF(Py_None);
856 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000857}
Guido van Rossum21142a01999-01-08 21:05:37 +0000858
859static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861{
Victor Stinner8c62be82010-05-06 00:08:46 +0000862 PyObject *opath1 = NULL;
863 char *path1;
864 int res;
865 if (!PyArg_ParseTuple(args, format,
866 PyUnicode_FSConverter, &opath1))
867 return NULL;
868 path1 = PyBytes_AsString(opath1);
869 Py_BEGIN_ALLOW_THREADS
870 res = (*func)(path1);
871 Py_END_ALLOW_THREADS
872 if (res < 0)
873 return posix_error_with_allocated_filename(opath1);
874 Py_DECREF(opath1);
875 Py_INCREF(Py_None);
876 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000877}
878
Barry Warsaw53699e91996-12-10 23:23:01 +0000879static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000880posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000881 char *format,
882 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000883{
Victor Stinner8c62be82010-05-06 00:08:46 +0000884 PyObject *opath1 = NULL, *opath2 = NULL;
885 char *path1, *path2;
886 int res;
887 if (!PyArg_ParseTuple(args, format,
888 PyUnicode_FSConverter, &opath1,
889 PyUnicode_FSConverter, &opath2)) {
890 return NULL;
891 }
892 path1 = PyBytes_AsString(opath1);
893 path2 = PyBytes_AsString(opath2);
894 Py_BEGIN_ALLOW_THREADS
895 res = (*func)(path1, path2);
896 Py_END_ALLOW_THREADS
897 Py_DECREF(opath1);
898 Py_DECREF(opath2);
899 if (res != 0)
900 /* XXX how to report both path1 and path2??? */
901 return posix_error();
902 Py_INCREF(Py_None);
903 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000904}
905
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000906#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000907static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000908win32_1str(PyObject* args, char* func,
909 char* format, BOOL (__stdcall *funcA)(LPCSTR),
910 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000911{
Victor Stinner8c62be82010-05-06 00:08:46 +0000912 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100913 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +0000914 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000915
Victor Stinnereb5657a2011-09-30 01:44:27 +0200916 if (PyArg_ParseTuple(args, wformat, &uni))
917 {
918 wchar_t *wstr = PyUnicode_AsUnicode(uni);
919 if (wstr == NULL)
920 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000921 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +0200922 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +0000923 Py_END_ALLOW_THREADS
924 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +0200925 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +0000926 Py_INCREF(Py_None);
927 return Py_None;
928 }
Victor Stinnereb5657a2011-09-30 01:44:27 +0200929 PyErr_Clear();
930
Victor Stinner8c62be82010-05-06 00:08:46 +0000931 if (!PyArg_ParseTuple(args, format, &ansi))
932 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100933 if (win32_warn_bytes_api())
934 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000935 Py_BEGIN_ALLOW_THREADS
936 result = funcA(ansi);
937 Py_END_ALLOW_THREADS
938 if (!result)
939 return win32_error(func, ansi);
940 Py_INCREF(Py_None);
941 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000942
943}
944
945/* This is a reimplementation of the C library's chdir function,
946 but one that produces Win32 errors instead of DOS error codes.
947 chdir is essentially a wrapper around SetCurrentDirectory; however,
948 it also needs to set "magic" environment variables indicating
949 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000950static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000951win32_chdir(LPCSTR path)
952{
Victor Stinner8c62be82010-05-06 00:08:46 +0000953 char new_path[MAX_PATH+1];
954 int result;
955 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000956
Victor Stinner8c62be82010-05-06 00:08:46 +0000957 if(!SetCurrentDirectoryA(path))
958 return FALSE;
959 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
960 if (!result)
961 return FALSE;
962 /* In the ANSI API, there should not be any paths longer
963 than MAX_PATH. */
964 assert(result <= MAX_PATH+1);
965 if (strncmp(new_path, "\\\\", 2) == 0 ||
966 strncmp(new_path, "//", 2) == 0)
967 /* UNC path, nothing to do. */
968 return TRUE;
969 env[1] = new_path[0];
970 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000971}
972
973/* The Unicode version differs from the ANSI version
974 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000975static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000976win32_wchdir(LPCWSTR path)
977{
Victor Stinner8c62be82010-05-06 00:08:46 +0000978 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
979 int result;
980 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000981
Victor Stinner8c62be82010-05-06 00:08:46 +0000982 if(!SetCurrentDirectoryW(path))
983 return FALSE;
984 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
985 if (!result)
986 return FALSE;
987 if (result > MAX_PATH+1) {
988 new_path = malloc(result * sizeof(wchar_t));
989 if (!new_path) {
990 SetLastError(ERROR_OUTOFMEMORY);
991 return FALSE;
992 }
993 result = GetCurrentDirectoryW(result, new_path);
994 if (!result) {
995 free(new_path);
996 return FALSE;
997 }
998 }
999 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1000 wcsncmp(new_path, L"//", 2) == 0)
1001 /* UNC path, nothing to do. */
1002 return TRUE;
1003 env[1] = new_path[0];
1004 result = SetEnvironmentVariableW(env, new_path);
1005 if (new_path != _new_path)
1006 free(new_path);
1007 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001008}
1009#endif
1010
Martin v. Löwis14694662006-02-03 12:54:16 +00001011#ifdef MS_WINDOWS
1012/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1013 - time stamps are restricted to second resolution
1014 - file modification times suffer from forth-and-back conversions between
1015 UTC and local time
1016 Therefore, we implement our own stat, based on the Win32 API directly.
1017*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001018#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001019
1020struct win32_stat{
1021 int st_dev;
1022 __int64 st_ino;
1023 unsigned short st_mode;
1024 int st_nlink;
1025 int st_uid;
1026 int st_gid;
1027 int st_rdev;
1028 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001029 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001030 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001031 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001032 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001033 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001034 int st_ctime_nsec;
1035};
1036
1037static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1038
1039static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001040FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001041{
Victor Stinner8c62be82010-05-06 00:08:46 +00001042 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1043 /* Cannot simply cast and dereference in_ptr,
1044 since it might not be aligned properly */
1045 __int64 in;
1046 memcpy(&in, in_ptr, sizeof(in));
1047 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001048 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001049}
1050
Thomas Wouters477c8d52006-05-27 19:21:47 +00001051static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001052time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001053{
Victor Stinner8c62be82010-05-06 00:08:46 +00001054 /* XXX endianness */
1055 __int64 out;
1056 out = time_in + secs_between_epochs;
1057 out = out * 10000000 + nsec_in / 100;
1058 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001059}
1060
Martin v. Löwis14694662006-02-03 12:54:16 +00001061/* Below, we *know* that ugo+r is 0444 */
1062#if _S_IREAD != 0400
1063#error Unsupported C library
1064#endif
1065static int
1066attributes_to_mode(DWORD attr)
1067{
Victor Stinner8c62be82010-05-06 00:08:46 +00001068 int m = 0;
1069 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1070 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1071 else
1072 m |= _S_IFREG;
1073 if (attr & FILE_ATTRIBUTE_READONLY)
1074 m |= 0444;
1075 else
1076 m |= 0666;
1077 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001078}
1079
1080static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001081attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001082{
Victor Stinner8c62be82010-05-06 00:08:46 +00001083 memset(result, 0, sizeof(*result));
1084 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1085 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1086 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1087 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1088 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001089 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001090 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001091 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1092 /* first clear the S_IFMT bits */
1093 result->st_mode ^= (result->st_mode & 0170000);
1094 /* now set the bits that make this a symlink */
1095 result->st_mode |= 0120000;
1096 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001097
Victor Stinner8c62be82010-05-06 00:08:46 +00001098 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001099}
1100
Guido van Rossumd8faa362007-04-27 19:54:29 +00001101static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001102attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001103{
Victor Stinner8c62be82010-05-06 00:08:46 +00001104 HANDLE hFindFile;
1105 WIN32_FIND_DATAA FileData;
1106 hFindFile = FindFirstFileA(pszFile, &FileData);
1107 if (hFindFile == INVALID_HANDLE_VALUE)
1108 return FALSE;
1109 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001110 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001111 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112 info->dwFileAttributes = FileData.dwFileAttributes;
1113 info->ftCreationTime = FileData.ftCreationTime;
1114 info->ftLastAccessTime = FileData.ftLastAccessTime;
1115 info->ftLastWriteTime = FileData.ftLastWriteTime;
1116 info->nFileSizeHigh = FileData.nFileSizeHigh;
1117 info->nFileSizeLow = FileData.nFileSizeLow;
1118/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001119 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1120 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001121 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001122}
1123
1124static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001125attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001126{
Victor Stinner8c62be82010-05-06 00:08:46 +00001127 HANDLE hFindFile;
1128 WIN32_FIND_DATAW FileData;
1129 hFindFile = FindFirstFileW(pszFile, &FileData);
1130 if (hFindFile == INVALID_HANDLE_VALUE)
1131 return FALSE;
1132 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001133 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001134 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001135 info->dwFileAttributes = FileData.dwFileAttributes;
1136 info->ftCreationTime = FileData.ftCreationTime;
1137 info->ftLastAccessTime = FileData.ftLastAccessTime;
1138 info->ftLastWriteTime = FileData.ftLastWriteTime;
1139 info->nFileSizeHigh = FileData.nFileSizeHigh;
1140 info->nFileSizeLow = FileData.nFileSizeLow;
1141/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001142 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1143 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001144 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001145}
1146
Brian Curtind25aef52011-06-13 15:16:04 -05001147/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1148static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001149static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1150 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001151static int
Brian Curtind25aef52011-06-13 15:16:04 -05001152check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001153{
Brian Curtind25aef52011-06-13 15:16:04 -05001154 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001155 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1156 DWORD);
1157
Brian Curtind25aef52011-06-13 15:16:04 -05001158 /* only recheck */
1159 if (!has_GetFinalPathNameByHandle)
1160 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001161 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001162 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1163 "GetFinalPathNameByHandleA");
1164 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1165 "GetFinalPathNameByHandleW");
1166 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1167 Py_GetFinalPathNameByHandleW;
1168 }
1169 return has_GetFinalPathNameByHandle;
1170}
1171
1172static BOOL
1173get_target_path(HANDLE hdl, wchar_t **target_path)
1174{
1175 int buf_size, result_length;
1176 wchar_t *buf;
1177
1178 /* We have a good handle to the target, use it to determine
1179 the target path name (then we'll call lstat on it). */
1180 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1181 VOLUME_NAME_DOS);
1182 if(!buf_size)
1183 return FALSE;
1184
1185 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001186 if (!buf) {
1187 SetLastError(ERROR_OUTOFMEMORY);
1188 return FALSE;
1189 }
1190
Brian Curtind25aef52011-06-13 15:16:04 -05001191 result_length = Py_GetFinalPathNameByHandleW(hdl,
1192 buf, buf_size, VOLUME_NAME_DOS);
1193
1194 if(!result_length) {
1195 free(buf);
1196 return FALSE;
1197 }
1198
1199 if(!CloseHandle(hdl)) {
1200 free(buf);
1201 return FALSE;
1202 }
1203
1204 buf[result_length] = 0;
1205
1206 *target_path = buf;
1207 return TRUE;
1208}
1209
1210static int
1211win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1212 BOOL traverse);
1213static int
1214win32_xstat_impl(const char *path, struct win32_stat *result,
1215 BOOL traverse)
1216{
Victor Stinner26de69d2011-06-17 15:15:38 +02001217 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001218 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001219 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001220 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001221 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001222 const char *dot;
1223
Brian Curtind25aef52011-06-13 15:16:04 -05001224 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001225 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1226 traverse reparse point. */
1227 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001228 }
1229
Brian Curtinf5e76d02010-11-24 13:14:05 +00001230 hFile = CreateFileA(
1231 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001232 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001233 0, /* share mode */
1234 NULL, /* security attributes */
1235 OPEN_EXISTING,
1236 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001237 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1238 Because of this, calls like GetFinalPathNameByHandle will return
1239 the symlink path agin and not the actual final path. */
1240 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1241 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001242 NULL);
1243
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001244 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001245 /* Either the target doesn't exist, or we don't have access to
1246 get a handle to it. If the former, we need to return an error.
1247 If the latter, we can use attributes_from_dir. */
1248 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001249 return -1;
1250 /* Could not get attributes on open file. Fall back to
1251 reading the directory. */
1252 if (!attributes_from_dir(path, &info, &reparse_tag))
1253 /* Very strange. This should not fail now */
1254 return -1;
1255 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1256 if (traverse) {
1257 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001258 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001259 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001260 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001261 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001262 } else {
1263 if (!GetFileInformationByHandle(hFile, &info)) {
1264 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001265 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001266 }
1267 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001268 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1269 return -1;
1270
1271 /* Close the outer open file handle now that we're about to
1272 reopen it with different flags. */
1273 if (!CloseHandle(hFile))
1274 return -1;
1275
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001276 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001277 /* In order to call GetFinalPathNameByHandle we need to open
1278 the file without the reparse handling flag set. */
1279 hFile2 = CreateFileA(
1280 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1281 NULL, OPEN_EXISTING,
1282 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1283 NULL);
1284 if (hFile2 == INVALID_HANDLE_VALUE)
1285 return -1;
1286
1287 if (!get_target_path(hFile2, &target_path))
1288 return -1;
1289
1290 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001291 free(target_path);
1292 return code;
1293 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001294 } else
1295 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001296 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001297 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001298
1299 /* Set S_IEXEC if it is an .exe, .bat, ... */
1300 dot = strrchr(path, '.');
1301 if (dot) {
1302 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1303 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1304 result->st_mode |= 0111;
1305 }
1306 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001307}
1308
1309static int
Brian Curtind25aef52011-06-13 15:16:04 -05001310win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1311 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001312{
1313 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001314 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001315 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001316 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001317 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001318 const wchar_t *dot;
1319
Brian Curtind25aef52011-06-13 15:16:04 -05001320 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001321 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1322 traverse reparse point. */
1323 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001324 }
1325
Brian Curtinf5e76d02010-11-24 13:14:05 +00001326 hFile = CreateFileW(
1327 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001328 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001329 0, /* share mode */
1330 NULL, /* security attributes */
1331 OPEN_EXISTING,
1332 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001333 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1334 Because of this, calls like GetFinalPathNameByHandle will return
1335 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001336 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001337 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001338 NULL);
1339
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001340 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001341 /* Either the target doesn't exist, or we don't have access to
1342 get a handle to it. If the former, we need to return an error.
1343 If the latter, we can use attributes_from_dir. */
1344 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001345 return -1;
1346 /* Could not get attributes on open file. Fall back to
1347 reading the directory. */
1348 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1349 /* Very strange. This should not fail now */
1350 return -1;
1351 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1352 if (traverse) {
1353 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001354 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001355 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001356 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001357 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001358 } else {
1359 if (!GetFileInformationByHandle(hFile, &info)) {
1360 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001361 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001362 }
1363 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001364 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1365 return -1;
1366
1367 /* Close the outer open file handle now that we're about to
1368 reopen it with different flags. */
1369 if (!CloseHandle(hFile))
1370 return -1;
1371
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001372 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001373 /* In order to call GetFinalPathNameByHandle we need to open
1374 the file without the reparse handling flag set. */
1375 hFile2 = CreateFileW(
1376 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1377 NULL, OPEN_EXISTING,
1378 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1379 NULL);
1380 if (hFile2 == INVALID_HANDLE_VALUE)
1381 return -1;
1382
1383 if (!get_target_path(hFile2, &target_path))
1384 return -1;
1385
1386 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001387 free(target_path);
1388 return code;
1389 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001390 } else
1391 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001392 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001393 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001394
1395 /* Set S_IEXEC if it is an .exe, .bat, ... */
1396 dot = wcsrchr(path, '.');
1397 if (dot) {
1398 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1399 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1400 result->st_mode |= 0111;
1401 }
1402 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001403}
1404
1405static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001406win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001407{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001408 /* Protocol violation: we explicitly clear errno, instead of
1409 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001410 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001411 errno = 0;
1412 return code;
1413}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001414
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001415static int
1416win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1417{
1418 /* Protocol violation: we explicitly clear errno, instead of
1419 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001420 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001421 errno = 0;
1422 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001423}
Brian Curtind25aef52011-06-13 15:16:04 -05001424/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001425
1426 In Posix, stat automatically traverses symlinks and returns the stat
1427 structure for the target. In Windows, the equivalent GetFileAttributes by
1428 default does not traverse symlinks and instead returns attributes for
1429 the symlink.
1430
1431 Therefore, win32_lstat will get the attributes traditionally, and
1432 win32_stat will first explicitly resolve the symlink target and then will
1433 call win32_lstat on that result.
1434
Ezio Melotti4969f702011-03-15 05:59:46 +02001435 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001436
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001437static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001438win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001439{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001440 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001441}
1442
Victor Stinner8c62be82010-05-06 00:08:46 +00001443static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001444win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001445{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001446 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001447}
1448
1449static int
1450win32_stat(const char* path, struct win32_stat *result)
1451{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001452 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001453}
1454
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001455static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001456win32_stat_w(const wchar_t* path, struct win32_stat *result)
1457{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001458 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001459}
1460
1461static int
1462win32_fstat(int file_number, struct win32_stat *result)
1463{
Victor Stinner8c62be82010-05-06 00:08:46 +00001464 BY_HANDLE_FILE_INFORMATION info;
1465 HANDLE h;
1466 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001467
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001469
Victor Stinner8c62be82010-05-06 00:08:46 +00001470 /* Protocol violation: we explicitly clear errno, instead of
1471 setting it to a POSIX error. Callers should use GetLastError. */
1472 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001473
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 if (h == INVALID_HANDLE_VALUE) {
1475 /* This is really a C library error (invalid file handle).
1476 We set the Win32 error to the closes one matching. */
1477 SetLastError(ERROR_INVALID_HANDLE);
1478 return -1;
1479 }
1480 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001481
Victor Stinner8c62be82010-05-06 00:08:46 +00001482 type = GetFileType(h);
1483 if (type == FILE_TYPE_UNKNOWN) {
1484 DWORD error = GetLastError();
1485 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001486 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001487 }
1488 /* else: valid but unknown file */
1489 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001490
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 if (type != FILE_TYPE_DISK) {
1492 if (type == FILE_TYPE_CHAR)
1493 result->st_mode = _S_IFCHR;
1494 else if (type == FILE_TYPE_PIPE)
1495 result->st_mode = _S_IFIFO;
1496 return 0;
1497 }
1498
1499 if (!GetFileInformationByHandle(h, &info)) {
1500 return -1;
1501 }
1502
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001503 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001504 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1506 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001507}
1508
1509#endif /* MS_WINDOWS */
1510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001511PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001512"stat_result: Result from stat or lstat.\n\n\
1513This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001514 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001515or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1516\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001517Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1518or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001519\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001520See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001521
1522static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 {"st_mode", "protection bits"},
1524 {"st_ino", "inode"},
1525 {"st_dev", "device"},
1526 {"st_nlink", "number of hard links"},
1527 {"st_uid", "user ID of owner"},
1528 {"st_gid", "group ID of owner"},
1529 {"st_size", "total size, in bytes"},
1530 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1531 {NULL, "integer time of last access"},
1532 {NULL, "integer time of last modification"},
1533 {NULL, "integer time of last change"},
1534 {"st_atime", "time of last access"},
1535 {"st_mtime", "time of last modification"},
1536 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001537#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001538 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001539#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001540#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001542#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001543#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001545#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001546#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001548#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001549#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001550 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001551#endif
1552#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001554#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001556};
1557
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001558#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001559#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001560#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001561#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001562#endif
1563
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001564#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001565#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1566#else
1567#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1568#endif
1569
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001570#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001571#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1572#else
1573#define ST_RDEV_IDX ST_BLOCKS_IDX
1574#endif
1575
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001576#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1577#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1578#else
1579#define ST_FLAGS_IDX ST_RDEV_IDX
1580#endif
1581
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001582#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001583#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001584#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001585#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001586#endif
1587
1588#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1589#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1590#else
1591#define ST_BIRTHTIME_IDX ST_GEN_IDX
1592#endif
1593
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001594static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001595 "stat_result", /* name */
1596 stat_result__doc__, /* doc */
1597 stat_result_fields,
1598 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001599};
1600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001601PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001602"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1603This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001604 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001605or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001606\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001607See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001608
1609static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001610 {"f_bsize", },
1611 {"f_frsize", },
1612 {"f_blocks", },
1613 {"f_bfree", },
1614 {"f_bavail", },
1615 {"f_files", },
1616 {"f_ffree", },
1617 {"f_favail", },
1618 {"f_flag", },
1619 {"f_namemax",},
1620 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001621};
1622
1623static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001624 "statvfs_result", /* name */
1625 statvfs_result__doc__, /* doc */
1626 statvfs_result_fields,
1627 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001628};
1629
Ross Lagerwall7807c352011-03-17 20:20:30 +02001630#if defined(HAVE_WAITID) && !defined(__APPLE__)
1631PyDoc_STRVAR(waitid_result__doc__,
1632"waitid_result: Result from waitid.\n\n\
1633This object may be accessed either as a tuple of\n\
1634 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1635or via the attributes si_pid, si_uid, and so on.\n\
1636\n\
1637See os.waitid for more information.");
1638
1639static PyStructSequence_Field waitid_result_fields[] = {
1640 {"si_pid", },
1641 {"si_uid", },
1642 {"si_signo", },
1643 {"si_status", },
1644 {"si_code", },
1645 {0}
1646};
1647
1648static PyStructSequence_Desc waitid_result_desc = {
1649 "waitid_result", /* name */
1650 waitid_result__doc__, /* doc */
1651 waitid_result_fields,
1652 5
1653};
1654static PyTypeObject WaitidResultType;
1655#endif
1656
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001657static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001658static PyTypeObject StatResultType;
1659static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001660#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001661static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001662#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001663static newfunc structseq_new;
1664
1665static PyObject *
1666statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1667{
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 PyStructSequence *result;
1669 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001670
Victor Stinner8c62be82010-05-06 00:08:46 +00001671 result = (PyStructSequence*)structseq_new(type, args, kwds);
1672 if (!result)
1673 return NULL;
1674 /* If we have been initialized from a tuple,
1675 st_?time might be set to None. Initialize it
1676 from the int slots. */
1677 for (i = 7; i <= 9; i++) {
1678 if (result->ob_item[i+3] == Py_None) {
1679 Py_DECREF(Py_None);
1680 Py_INCREF(result->ob_item[i]);
1681 result->ob_item[i+3] = result->ob_item[i];
1682 }
1683 }
1684 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001685}
1686
1687
1688
1689/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001690static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001691
1692PyDoc_STRVAR(stat_float_times__doc__,
1693"stat_float_times([newval]) -> oldval\n\n\
1694Determine whether os.[lf]stat represents time stamps as float objects.\n\
1695If newval is True, future calls to stat() return floats, if it is False,\n\
1696future calls return ints. \n\
1697If newval is omitted, return the current setting.\n");
1698
1699static PyObject*
1700stat_float_times(PyObject* self, PyObject *args)
1701{
Victor Stinner8c62be82010-05-06 00:08:46 +00001702 int newval = -1;
1703 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1704 return NULL;
1705 if (newval == -1)
1706 /* Return old value */
1707 return PyBool_FromLong(_stat_float_times);
1708 _stat_float_times = newval;
1709 Py_INCREF(Py_None);
1710 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001711}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001712
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001713static void
1714fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1715{
Victor Stinner8c62be82010-05-06 00:08:46 +00001716 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001717#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001718 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001719#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001720 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001721#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001722 if (!ival)
1723 return;
1724 if (_stat_float_times) {
1725 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1726 } else {
1727 fval = ival;
1728 Py_INCREF(fval);
1729 }
1730 PyStructSequence_SET_ITEM(v, index, ival);
1731 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001732}
1733
Tim Peters5aa91602002-01-30 05:46:57 +00001734/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001735 (used by posix_stat() and posix_fstat()) */
1736static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001737_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001738{
Victor Stinner8c62be82010-05-06 00:08:46 +00001739 unsigned long ansec, mnsec, cnsec;
1740 PyObject *v = PyStructSequence_New(&StatResultType);
1741 if (v == NULL)
1742 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001743
Victor Stinner8c62be82010-05-06 00:08:46 +00001744 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001745#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001746 PyStructSequence_SET_ITEM(v, 1,
1747 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001748#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001749 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001750#endif
1751#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001752 PyStructSequence_SET_ITEM(v, 2,
1753 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001754#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001755 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001756#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001757 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1758 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1759 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001760#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001761 PyStructSequence_SET_ITEM(v, 6,
1762 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001763#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001765#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001766
Martin v. Löwis14694662006-02-03 12:54:16 +00001767#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 ansec = st->st_atim.tv_nsec;
1769 mnsec = st->st_mtim.tv_nsec;
1770 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001771#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001772 ansec = st->st_atimespec.tv_nsec;
1773 mnsec = st->st_mtimespec.tv_nsec;
1774 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001775#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 ansec = st->st_atime_nsec;
1777 mnsec = st->st_mtime_nsec;
1778 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001779#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001781#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 fill_time(v, 7, st->st_atime, ansec);
1783 fill_time(v, 8, st->st_mtime, mnsec);
1784 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001785
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001786#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1788 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001790#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1792 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001793#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001794#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001795 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1796 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001797#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001798#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001799 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1800 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001801#endif
1802#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 {
1804 PyObject *val;
1805 unsigned long bsec,bnsec;
1806 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001807#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001808 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001809#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001810 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001811#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001812 if (_stat_float_times) {
1813 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1814 } else {
1815 val = PyLong_FromLong((long)bsec);
1816 }
1817 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1818 val);
1819 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001820#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001821#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001822 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1823 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001824#endif
Fred Drake699f3522000-06-29 21:12:41 +00001825
Victor Stinner8c62be82010-05-06 00:08:46 +00001826 if (PyErr_Occurred()) {
1827 Py_DECREF(v);
1828 return NULL;
1829 }
Fred Drake699f3522000-06-29 21:12:41 +00001830
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001832}
1833
Barry Warsaw53699e91996-12-10 23:23:01 +00001834static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001835posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001836 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001837#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001839#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001841#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 char *wformat,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001843 int (*wstatfunc)(const wchar_t *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001844{
Victor Stinner8c62be82010-05-06 00:08:46 +00001845 STRUCT_STAT st;
1846 PyObject *opath;
1847 char *path;
1848 int res;
1849 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001850
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001851#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001852 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001853 if (PyArg_ParseTuple(args, wformat, &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001854 wchar_t *wpath = PyUnicode_AsUnicode(po);
1855 if (wpath == NULL)
1856 return NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00001857
Victor Stinner8c62be82010-05-06 00:08:46 +00001858 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 res = wstatfunc(wpath, &st);
1860 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001861
Victor Stinner8c62be82010-05-06 00:08:46 +00001862 if (res != 0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001863 return win32_error_object("stat", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00001864 return _pystat_fromstructstat(&st);
1865 }
1866 /* Drop the argument parsing error as narrow strings
1867 are also valid. */
1868 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001869#endif
1870
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 if (!PyArg_ParseTuple(args, format,
1872 PyUnicode_FSConverter, &opath))
1873 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001874#ifdef MS_WINDOWS
1875 if (win32_warn_bytes_api()) {
1876 Py_DECREF(opath);
1877 return NULL;
1878 }
1879#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001880 path = PyBytes_AsString(opath);
1881 Py_BEGIN_ALLOW_THREADS
1882 res = (*statfunc)(path, &st);
1883 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001884
Victor Stinner8c62be82010-05-06 00:08:46 +00001885 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001886#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001888#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001890#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001891 }
1892 else
1893 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001894
Victor Stinner8c62be82010-05-06 00:08:46 +00001895 Py_DECREF(opath);
1896 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001897}
1898
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001899/* POSIX methods */
1900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001901PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001902"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001903Use the real uid/gid to test for access to a path. Note that most\n\
1904operations will use the effective uid/gid, therefore this routine can\n\
1905be used in a suid/sgid environment to test if the invoking user has the\n\
1906specified access to the path. The mode argument can be F_OK to test\n\
1907existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001908
1909static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001910posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001911{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001912 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 int mode;
1914
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001915#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001916 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02001917 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001918 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001919 wchar_t* wpath = PyUnicode_AsUnicode(po);
1920 if (wpath == NULL)
1921 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001922 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001923 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 Py_END_ALLOW_THREADS
1925 goto finish;
1926 }
1927 /* Drop the argument parsing error as narrow strings
1928 are also valid. */
1929 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001930 if (!PyArg_ParseTuple(args, "yi:access", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001932 if (win32_warn_bytes_api())
1933 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 Py_BEGIN_ALLOW_THREADS
1935 attr = GetFileAttributesA(path);
1936 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001937finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 if (attr == 0xFFFFFFFF)
1939 /* File does not exist, or cannot read attributes */
1940 return PyBool_FromLong(0);
1941 /* Access is possible if either write access wasn't requested, or
1942 the file isn't read-only, or if it's a directory, as there are
1943 no read-only directories on Windows. */
1944 return PyBool_FromLong(!(mode & 2)
1945 || !(attr & FILE_ATTRIBUTE_READONLY)
1946 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001947#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001948 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00001949 int res;
1950 if (!PyArg_ParseTuple(args, "O&i:access",
1951 PyUnicode_FSConverter, &opath, &mode))
1952 return NULL;
1953 path = PyBytes_AsString(opath);
1954 Py_BEGIN_ALLOW_THREADS
1955 res = access(path, mode);
1956 Py_END_ALLOW_THREADS
1957 Py_DECREF(opath);
1958 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001959#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001960}
1961
Guido van Rossumd371ff11999-01-25 16:12:23 +00001962#ifndef F_OK
1963#define F_OK 0
1964#endif
1965#ifndef R_OK
1966#define R_OK 4
1967#endif
1968#ifndef W_OK
1969#define W_OK 2
1970#endif
1971#ifndef X_OK
1972#define X_OK 1
1973#endif
1974
1975#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001976PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001977"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001978Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001979
1980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001981posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001982{
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 int id;
1984 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001985
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1987 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001988
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001989#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 /* file descriptor 0 only, the default input device (stdin) */
1991 if (id == 0) {
1992 ret = ttyname();
1993 }
1994 else {
1995 ret = NULL;
1996 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001997#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001998 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001999#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 if (ret == NULL)
2001 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002002 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002003}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002004#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002005
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002006#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002007PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002008"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002009Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002010
2011static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002012posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002013{
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 char *ret;
2015 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002016
Greg Wardb48bc172000-03-01 21:51:56 +00002017#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002018 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002019#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002020 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002021#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 if (ret == NULL)
2023 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002024 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002025}
2026#endif
2027
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002029"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002030Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031
Barry Warsaw53699e91996-12-10 23:23:01 +00002032static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002033posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002034{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002035#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002037#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00002039#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002041#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002043#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044}
2045
Fred Drake4d1e64b2002-04-15 19:40:07 +00002046#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002048"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00002049Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002050opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002051
2052static PyObject *
2053posix_fchdir(PyObject *self, PyObject *fdobj)
2054{
Victor Stinner8c62be82010-05-06 00:08:46 +00002055 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002056}
2057#endif /* HAVE_FCHDIR */
2058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002060PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002061"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002063
Barry Warsaw53699e91996-12-10 23:23:01 +00002064static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002065posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002066{
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 PyObject *opath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002068 const char *path = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 int i;
2070 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002071#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002072 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002073 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00002074 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002075 wchar_t *wpath = PyUnicode_AsUnicode(po);
2076 if (wpath == NULL)
2077 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002078 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002079 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002080 if (attr != 0xFFFFFFFF) {
2081 if (i & _S_IWRITE)
2082 attr &= ~FILE_ATTRIBUTE_READONLY;
2083 else
2084 attr |= FILE_ATTRIBUTE_READONLY;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002085 res = SetFileAttributesW(wpath, attr);
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 }
2087 else
2088 res = 0;
2089 Py_END_ALLOW_THREADS
2090 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02002091 return win32_error_object("chmod", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 Py_INCREF(Py_None);
2093 return Py_None;
2094 }
2095 /* Drop the argument parsing error as narrow strings
2096 are also valid. */
2097 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002098
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002099 if (!PyArg_ParseTuple(args, "yi:chmod", &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002101 if (win32_warn_bytes_api())
2102 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 Py_BEGIN_ALLOW_THREADS
2104 attr = GetFileAttributesA(path);
2105 if (attr != 0xFFFFFFFF) {
2106 if (i & _S_IWRITE)
2107 attr &= ~FILE_ATTRIBUTE_READONLY;
2108 else
2109 attr |= FILE_ATTRIBUTE_READONLY;
2110 res = SetFileAttributesA(path, attr);
2111 }
2112 else
2113 res = 0;
2114 Py_END_ALLOW_THREADS
2115 if (!res) {
2116 win32_error("chmod", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002117 return NULL;
2118 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002119 Py_INCREF(Py_None);
2120 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002121#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002122 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2123 &opath, &i))
2124 return NULL;
2125 path = PyBytes_AsString(opath);
2126 Py_BEGIN_ALLOW_THREADS
2127 res = chmod(path, i);
2128 Py_END_ALLOW_THREADS
2129 if (res < 0)
2130 return posix_error_with_allocated_filename(opath);
2131 Py_DECREF(opath);
2132 Py_INCREF(Py_None);
2133 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002134#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002135}
2136
Christian Heimes4e30a842007-11-30 22:12:06 +00002137#ifdef HAVE_FCHMOD
2138PyDoc_STRVAR(posix_fchmod__doc__,
2139"fchmod(fd, mode)\n\n\
2140Change the access permissions of the file given by file\n\
2141descriptor fd.");
2142
2143static PyObject *
2144posix_fchmod(PyObject *self, PyObject *args)
2145{
Victor Stinner8c62be82010-05-06 00:08:46 +00002146 int fd, mode, res;
2147 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2148 return NULL;
2149 Py_BEGIN_ALLOW_THREADS
2150 res = fchmod(fd, mode);
2151 Py_END_ALLOW_THREADS
2152 if (res < 0)
2153 return posix_error();
2154 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002155}
2156#endif /* HAVE_FCHMOD */
2157
2158#ifdef HAVE_LCHMOD
2159PyDoc_STRVAR(posix_lchmod__doc__,
2160"lchmod(path, mode)\n\n\
2161Change the access permissions of a file. If path is a symlink, this\n\
2162affects the link itself rather than the target.");
2163
2164static PyObject *
2165posix_lchmod(PyObject *self, PyObject *args)
2166{
Victor Stinner8c62be82010-05-06 00:08:46 +00002167 PyObject *opath;
2168 char *path;
2169 int i;
2170 int res;
2171 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2172 &opath, &i))
2173 return NULL;
2174 path = PyBytes_AsString(opath);
2175 Py_BEGIN_ALLOW_THREADS
2176 res = lchmod(path, i);
2177 Py_END_ALLOW_THREADS
2178 if (res < 0)
2179 return posix_error_with_allocated_filename(opath);
2180 Py_DECREF(opath);
2181 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002182}
2183#endif /* HAVE_LCHMOD */
2184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002185
Thomas Wouterscf297e42007-02-23 15:07:44 +00002186#ifdef HAVE_CHFLAGS
2187PyDoc_STRVAR(posix_chflags__doc__,
2188"chflags(path, flags)\n\n\
2189Set file flags.");
2190
2191static PyObject *
2192posix_chflags(PyObject *self, PyObject *args)
2193{
Victor Stinner8c62be82010-05-06 00:08:46 +00002194 PyObject *opath;
2195 char *path;
2196 unsigned long flags;
2197 int res;
2198 if (!PyArg_ParseTuple(args, "O&k:chflags",
2199 PyUnicode_FSConverter, &opath, &flags))
2200 return NULL;
2201 path = PyBytes_AsString(opath);
2202 Py_BEGIN_ALLOW_THREADS
2203 res = chflags(path, flags);
2204 Py_END_ALLOW_THREADS
2205 if (res < 0)
2206 return posix_error_with_allocated_filename(opath);
2207 Py_DECREF(opath);
2208 Py_INCREF(Py_None);
2209 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002210}
2211#endif /* HAVE_CHFLAGS */
2212
2213#ifdef HAVE_LCHFLAGS
2214PyDoc_STRVAR(posix_lchflags__doc__,
2215"lchflags(path, flags)\n\n\
2216Set file flags.\n\
2217This function will not follow symbolic links.");
2218
2219static PyObject *
2220posix_lchflags(PyObject *self, PyObject *args)
2221{
Victor Stinner8c62be82010-05-06 00:08:46 +00002222 PyObject *opath;
2223 char *path;
2224 unsigned long flags;
2225 int res;
2226 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2227 PyUnicode_FSConverter, &opath, &flags))
2228 return NULL;
2229 path = PyBytes_AsString(opath);
2230 Py_BEGIN_ALLOW_THREADS
2231 res = lchflags(path, flags);
2232 Py_END_ALLOW_THREADS
2233 if (res < 0)
2234 return posix_error_with_allocated_filename(opath);
2235 Py_DECREF(opath);
2236 Py_INCREF(Py_None);
2237 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002238}
2239#endif /* HAVE_LCHFLAGS */
2240
Martin v. Löwis244edc82001-10-04 22:44:26 +00002241#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002242PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002243"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002244Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002245
2246static PyObject *
2247posix_chroot(PyObject *self, PyObject *args)
2248{
Victor Stinner8c62be82010-05-06 00:08:46 +00002249 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002250}
2251#endif
2252
Guido van Rossum21142a01999-01-08 21:05:37 +00002253#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002254PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002255"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002256force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002257
2258static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002259posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002260{
Stefan Krah0e803b32010-11-26 16:16:47 +00002261 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002262}
2263#endif /* HAVE_FSYNC */
2264
Ross Lagerwall7807c352011-03-17 20:20:30 +02002265#ifdef HAVE_SYNC
2266PyDoc_STRVAR(posix_sync__doc__,
2267"sync()\n\n\
2268Force write of everything to disk.");
2269
2270static PyObject *
2271posix_sync(PyObject *self, PyObject *noargs)
2272{
2273 Py_BEGIN_ALLOW_THREADS
2274 sync();
2275 Py_END_ALLOW_THREADS
2276 Py_RETURN_NONE;
2277}
2278#endif
2279
Guido van Rossum21142a01999-01-08 21:05:37 +00002280#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002281
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002282#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002283extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2284#endif
2285
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002286PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002287"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002288force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002289 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002290
2291static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002292posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002293{
Stefan Krah0e803b32010-11-26 16:16:47 +00002294 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002295}
2296#endif /* HAVE_FDATASYNC */
2297
2298
Fredrik Lundh10723342000-07-10 16:38:09 +00002299#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002300PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002301"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002302Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002303
Barry Warsaw53699e91996-12-10 23:23:01 +00002304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002305posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002306{
Victor Stinner8c62be82010-05-06 00:08:46 +00002307 PyObject *opath;
2308 char *path;
2309 long uid, gid;
2310 int res;
2311 if (!PyArg_ParseTuple(args, "O&ll:chown",
2312 PyUnicode_FSConverter, &opath,
2313 &uid, &gid))
2314 return NULL;
2315 path = PyBytes_AsString(opath);
2316 Py_BEGIN_ALLOW_THREADS
2317 res = chown(path, (uid_t) uid, (gid_t) gid);
2318 Py_END_ALLOW_THREADS
2319 if (res < 0)
2320 return posix_error_with_allocated_filename(opath);
2321 Py_DECREF(opath);
2322 Py_INCREF(Py_None);
2323 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002324}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002325#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002326
Christian Heimes4e30a842007-11-30 22:12:06 +00002327#ifdef HAVE_FCHOWN
2328PyDoc_STRVAR(posix_fchown__doc__,
2329"fchown(fd, uid, gid)\n\n\
2330Change the owner and group id of the file given by file descriptor\n\
2331fd to the numeric uid and gid.");
2332
2333static PyObject *
2334posix_fchown(PyObject *self, PyObject *args)
2335{
Victor Stinner8c62be82010-05-06 00:08:46 +00002336 int fd;
2337 long uid, gid;
2338 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002339 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002340 return NULL;
2341 Py_BEGIN_ALLOW_THREADS
2342 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2343 Py_END_ALLOW_THREADS
2344 if (res < 0)
2345 return posix_error();
2346 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002347}
2348#endif /* HAVE_FCHOWN */
2349
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002350#ifdef HAVE_LCHOWN
2351PyDoc_STRVAR(posix_lchown__doc__,
2352"lchown(path, uid, gid)\n\n\
2353Change the owner and group id of path to the numeric uid and gid.\n\
2354This function will not follow symbolic links.");
2355
2356static PyObject *
2357posix_lchown(PyObject *self, PyObject *args)
2358{
Victor Stinner8c62be82010-05-06 00:08:46 +00002359 PyObject *opath;
2360 char *path;
2361 long uid, gid;
2362 int res;
2363 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2364 PyUnicode_FSConverter, &opath,
2365 &uid, &gid))
2366 return NULL;
2367 path = PyBytes_AsString(opath);
2368 Py_BEGIN_ALLOW_THREADS
2369 res = lchown(path, (uid_t) uid, (gid_t) gid);
2370 Py_END_ALLOW_THREADS
2371 if (res < 0)
2372 return posix_error_with_allocated_filename(opath);
2373 Py_DECREF(opath);
2374 Py_INCREF(Py_None);
2375 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002376}
2377#endif /* HAVE_LCHOWN */
2378
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002379
Guido van Rossum36bc6801995-06-14 22:54:23 +00002380#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002381static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002382posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002383{
Victor Stinner8c62be82010-05-06 00:08:46 +00002384 char buf[1026];
2385 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002386
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002387#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002388 if (!use_bytes) {
2389 wchar_t wbuf[1026];
2390 wchar_t *wbuf2 = wbuf;
2391 PyObject *resobj;
2392 DWORD len;
2393 Py_BEGIN_ALLOW_THREADS
2394 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2395 /* If the buffer is large enough, len does not include the
2396 terminating \0. If the buffer is too small, len includes
2397 the space needed for the terminator. */
2398 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2399 wbuf2 = malloc(len * sizeof(wchar_t));
2400 if (wbuf2)
2401 len = GetCurrentDirectoryW(len, wbuf2);
2402 }
2403 Py_END_ALLOW_THREADS
2404 if (!wbuf2) {
2405 PyErr_NoMemory();
2406 return NULL;
2407 }
2408 if (!len) {
2409 if (wbuf2 != wbuf) free(wbuf2);
2410 return win32_error("getcwdu", NULL);
2411 }
2412 resobj = PyUnicode_FromWideChar(wbuf2, len);
2413 if (wbuf2 != wbuf) free(wbuf2);
2414 return resobj;
2415 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002416
2417 if (win32_warn_bytes_api())
2418 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002419#endif
2420
Victor Stinner8c62be82010-05-06 00:08:46 +00002421 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002422#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002423 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002424#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002425 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002426#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002427 Py_END_ALLOW_THREADS
2428 if (res == NULL)
2429 return posix_error();
2430 if (use_bytes)
2431 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002432 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002433}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002434
2435PyDoc_STRVAR(posix_getcwd__doc__,
2436"getcwd() -> path\n\n\
2437Return a unicode string representing the current working directory.");
2438
2439static PyObject *
2440posix_getcwd_unicode(PyObject *self)
2441{
2442 return posix_getcwd(0);
2443}
2444
2445PyDoc_STRVAR(posix_getcwdb__doc__,
2446"getcwdb() -> path\n\n\
2447Return a bytes string representing the current working directory.");
2448
2449static PyObject *
2450posix_getcwd_bytes(PyObject *self)
2451{
2452 return posix_getcwd(1);
2453}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002454#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002455
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002456
Guido van Rossumb6775db1994-08-01 11:34:53 +00002457#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002458PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002459"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002460Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002461
Barry Warsaw53699e91996-12-10 23:23:01 +00002462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002463posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002464{
Victor Stinner8c62be82010-05-06 00:08:46 +00002465 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002466}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002467#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002468
Brian Curtin1b9df392010-11-24 20:24:31 +00002469#ifdef MS_WINDOWS
2470PyDoc_STRVAR(win32_link__doc__,
2471"link(src, dst)\n\n\
2472Create a hard link to a file.");
2473
2474static PyObject *
2475win32_link(PyObject *self, PyObject *args)
2476{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002477 PyObject *src, *dst;
2478 BOOL ok;
Brian Curtin1b9df392010-11-24 20:24:31 +00002479
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002480 if (PyArg_ParseTuple(args, "UU:link", &src, &dst))
Victor Stinnereb5657a2011-09-30 01:44:27 +02002481 {
2482 wchar_t *wsrc, *wdst;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002483
2484 wsrc = PyUnicode_AsUnicode(src);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002485 if (wsrc == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002486 goto error;
2487 wdst = PyUnicode_AsUnicode(dst);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002488 if (wdst == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002489 goto error;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002490
Brian Curtinfc889c42010-11-28 23:59:46 +00002491 Py_BEGIN_ALLOW_THREADS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002492 ok = CreateHardLinkW(wdst, wsrc, NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002493 Py_END_ALLOW_THREADS
2494
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002495 if (!ok)
Brian Curtinfc889c42010-11-28 23:59:46 +00002496 return win32_error("link", NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002497 Py_RETURN_NONE;
2498 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002499 else {
2500 PyErr_Clear();
2501 if (!PyArg_ParseTuple(args, "O&O&:link",
2502 PyUnicode_FSConverter, &src,
2503 PyUnicode_FSConverter, &dst))
2504 return NULL;
Brian Curtinfc889c42010-11-28 23:59:46 +00002505
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002506 if (win32_warn_bytes_api())
2507 goto error;
Brian Curtinfc889c42010-11-28 23:59:46 +00002508
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002509 Py_BEGIN_ALLOW_THREADS
2510 ok = CreateHardLinkA(PyBytes_AS_STRING(dst),
2511 PyBytes_AS_STRING(src),
2512 NULL);
2513 Py_END_ALLOW_THREADS
2514
2515 Py_XDECREF(src);
2516 Py_XDECREF(dst);
2517
2518 if (!ok)
2519 return win32_error("link", NULL);
2520 Py_RETURN_NONE;
2521
2522 error:
2523 Py_XDECREF(src);
2524 Py_XDECREF(dst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002525 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002526 }
Brian Curtin1b9df392010-11-24 20:24:31 +00002527}
2528#endif /* MS_WINDOWS */
2529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002530
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002531PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002532"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002533Return a list containing the names of the entries in the directory.\n\
2534\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002535 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002536\n\
2537The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002538entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002539
Barry Warsaw53699e91996-12-10 23:23:01 +00002540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002541posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002542{
Victor Stinner8c62be82010-05-06 00:08:46 +00002543 /* XXX Should redo this putting the (now four) versions of opendir
2544 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002545#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002546
Victor Stinner8c62be82010-05-06 00:08:46 +00002547 PyObject *d, *v;
2548 HANDLE hFindFile;
2549 BOOL result;
2550 WIN32_FIND_DATA FileData;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002551 const char *path;
2552 Py_ssize_t pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002553 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2554 char *bufptr = namebuf;
2555 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002556
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002557 PyObject *po = NULL;
2558 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002559 WIN32_FIND_DATAW wFileData;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002560 wchar_t *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002561
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002562 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002563 po_wchars = L".";
2564 len = 1;
2565 } else {
Victor Stinnerbeac78b2011-10-11 21:55:01 +02002566 po_wchars = PyUnicode_AsUnicodeAndSize(po, &len);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002567 if (po_wchars == NULL)
2568 return NULL;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002569 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002570 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2572 if (!wnamebuf) {
2573 PyErr_NoMemory();
2574 return NULL;
2575 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002576 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002577 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002578 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00002579 if (wch != L'/' && wch != L'\\' && wch != L':')
2580 wnamebuf[len++] = L'\\';
2581 wcscpy(wnamebuf + len, L"*.*");
2582 }
2583 if ((d = PyList_New(0)) == NULL) {
2584 free(wnamebuf);
2585 return NULL;
2586 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002587 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002588 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002589 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002590 if (hFindFile == INVALID_HANDLE_VALUE) {
2591 int error = GetLastError();
2592 if (error == ERROR_FILE_NOT_FOUND) {
2593 free(wnamebuf);
2594 return d;
2595 }
2596 Py_DECREF(d);
2597 win32_error_unicode("FindFirstFileW", wnamebuf);
2598 free(wnamebuf);
2599 return NULL;
2600 }
2601 do {
2602 /* Skip over . and .. */
2603 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2604 wcscmp(wFileData.cFileName, L"..") != 0) {
Victor Stinner9d3b93b2011-11-22 02:27:30 +01002605 v = PyUnicode_FromWideChar(wFileData.cFileName, wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00002606 if (v == NULL) {
2607 Py_DECREF(d);
2608 d = NULL;
2609 break;
2610 }
2611 if (PyList_Append(d, v) != 0) {
2612 Py_DECREF(v);
2613 Py_DECREF(d);
2614 d = NULL;
2615 break;
2616 }
2617 Py_DECREF(v);
2618 }
2619 Py_BEGIN_ALLOW_THREADS
2620 result = FindNextFileW(hFindFile, &wFileData);
2621 Py_END_ALLOW_THREADS
2622 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2623 it got to the end of the directory. */
2624 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2625 Py_DECREF(d);
2626 win32_error_unicode("FindNextFileW", wnamebuf);
2627 FindClose(hFindFile);
2628 free(wnamebuf);
2629 return NULL;
2630 }
2631 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002632
Victor Stinner8c62be82010-05-06 00:08:46 +00002633 if (FindClose(hFindFile) == FALSE) {
2634 Py_DECREF(d);
2635 win32_error_unicode("FindClose", wnamebuf);
2636 free(wnamebuf);
2637 return NULL;
2638 }
2639 free(wnamebuf);
2640 return d;
2641 }
2642 /* Drop the argument parsing error as narrow strings
2643 are also valid. */
2644 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002645
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002646 if (!PyArg_ParseTuple(args, "y#:listdir", &path, &pathlen))
Victor Stinner8c62be82010-05-06 00:08:46 +00002647 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002648 if (win32_warn_bytes_api())
2649 return NULL;
2650 if (pathlen+1 > MAX_PATH) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002651 PyErr_SetString(PyExc_ValueError, "path too long");
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 return NULL;
2653 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002654 strcpy(namebuf, path);
2655 len = pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002656 if (len > 0) {
2657 char ch = namebuf[len-1];
2658 if (ch != SEP && ch != ALTSEP && ch != ':')
2659 namebuf[len++] = '/';
2660 strcpy(namebuf + len, "*.*");
2661 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002662
Victor Stinner8c62be82010-05-06 00:08:46 +00002663 if ((d = PyList_New(0)) == NULL)
2664 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002665
Antoine Pitroub73caab2010-08-09 23:39:31 +00002666 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002667 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002668 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002669 if (hFindFile == INVALID_HANDLE_VALUE) {
2670 int error = GetLastError();
2671 if (error == ERROR_FILE_NOT_FOUND)
2672 return d;
2673 Py_DECREF(d);
2674 return win32_error("FindFirstFile", namebuf);
2675 }
2676 do {
2677 /* Skip over . and .. */
2678 if (strcmp(FileData.cFileName, ".") != 0 &&
2679 strcmp(FileData.cFileName, "..") != 0) {
2680 v = PyBytes_FromString(FileData.cFileName);
2681 if (v == NULL) {
2682 Py_DECREF(d);
2683 d = NULL;
2684 break;
2685 }
2686 if (PyList_Append(d, v) != 0) {
2687 Py_DECREF(v);
2688 Py_DECREF(d);
2689 d = NULL;
2690 break;
2691 }
2692 Py_DECREF(v);
2693 }
2694 Py_BEGIN_ALLOW_THREADS
2695 result = FindNextFile(hFindFile, &FileData);
2696 Py_END_ALLOW_THREADS
2697 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2698 it got to the end of the directory. */
2699 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2700 Py_DECREF(d);
2701 win32_error("FindNextFile", namebuf);
2702 FindClose(hFindFile);
2703 return NULL;
2704 }
2705 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002706
Victor Stinner8c62be82010-05-06 00:08:46 +00002707 if (FindClose(hFindFile) == FALSE) {
2708 Py_DECREF(d);
2709 return win32_error("FindClose", namebuf);
2710 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002711
Victor Stinner8c62be82010-05-06 00:08:46 +00002712 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002713
Tim Peters0bb44a42000-09-15 07:44:49 +00002714#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002715
2716#ifndef MAX_PATH
2717#define MAX_PATH CCHMAXPATH
2718#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002719 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002720 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002721 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002722 PyObject *d, *v;
2723 char namebuf[MAX_PATH+5];
2724 HDIR hdir = 1;
2725 ULONG srchcnt = 1;
2726 FILEFINDBUF3 ep;
2727 APIRET rc;
2728
Victor Stinner8c62be82010-05-06 00:08:46 +00002729 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002730 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002731 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002732 name = PyBytes_AsString(oname);
2733 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002734 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002735 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002736 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002737 return NULL;
2738 }
2739 strcpy(namebuf, name);
2740 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002741 if (*pt == ALTSEP)
2742 *pt = SEP;
2743 if (namebuf[len-1] != SEP)
2744 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002745 strcpy(namebuf + len, "*.*");
2746
Neal Norwitz6c913782007-10-14 03:23:09 +00002747 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002748 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002749 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002750 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002751
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002752 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2753 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002754 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002755 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2756 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2757 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002758
2759 if (rc != NO_ERROR) {
2760 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002761 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002762 }
2763
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002764 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002765 do {
2766 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002767 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002768 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002769
2770 strcpy(namebuf, ep.achName);
2771
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002772 /* Leave Case of Name Alone -- In Native Form */
2773 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002774
Christian Heimes72b710a2008-05-26 13:28:38 +00002775 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002776 if (v == NULL) {
2777 Py_DECREF(d);
2778 d = NULL;
2779 break;
2780 }
2781 if (PyList_Append(d, v) != 0) {
2782 Py_DECREF(v);
2783 Py_DECREF(d);
2784 d = NULL;
2785 break;
2786 }
2787 Py_DECREF(v);
2788 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2789 }
2790
Victor Stinnerdcb24032010-04-22 12:08:36 +00002791 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002792 return d;
2793#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002794 PyObject *oname;
2795 char *name;
2796 PyObject *d, *v;
2797 DIR *dirp;
2798 struct dirent *ep;
2799 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002800
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002802 /* v is never read, so it does not need to be initialized yet. */
2803 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002804 arg_is_unicode = 0;
2805 PyErr_Clear();
2806 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002807 oname = NULL;
2808 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002809 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002810 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002811 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002812 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002813 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002814 Py_BEGIN_ALLOW_THREADS
2815 dirp = opendir(name);
2816 Py_END_ALLOW_THREADS
2817 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 return posix_error_with_allocated_filename(oname);
2819 }
2820 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002821 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002822 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002823 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002824 Py_DECREF(oname);
2825 return NULL;
2826 }
2827 for (;;) {
2828 errno = 0;
2829 Py_BEGIN_ALLOW_THREADS
2830 ep = readdir(dirp);
2831 Py_END_ALLOW_THREADS
2832 if (ep == NULL) {
2833 if (errno == 0) {
2834 break;
2835 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002836 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002837 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002838 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002839 Py_DECREF(d);
2840 return posix_error_with_allocated_filename(oname);
2841 }
2842 }
2843 if (ep->d_name[0] == '.' &&
2844 (NAMLEN(ep) == 1 ||
2845 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2846 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002847 if (arg_is_unicode)
2848 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2849 else
2850 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002851 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002852 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 break;
2854 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002855 if (PyList_Append(d, v) != 0) {
2856 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002857 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002858 break;
2859 }
2860 Py_DECREF(v);
2861 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002862 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002863 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002864 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002865 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002866
Victor Stinner8c62be82010-05-06 00:08:46 +00002867 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002868
Tim Peters0bb44a42000-09-15 07:44:49 +00002869#endif /* which OS */
2870} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002871
Antoine Pitrou8250e232011-02-25 23:41:16 +00002872#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +01002873PyDoc_STRVAR(posix_flistdir__doc__,
2874"flistdir(fd) -> list_of_strings\n\n\
Charles-François Natali76961fa2012-01-10 20:25:09 +01002875Like listdir(), but uses a file descriptor instead.");
Antoine Pitrou8250e232011-02-25 23:41:16 +00002876
2877static PyObject *
Charles-François Natali77940902012-02-06 19:54:48 +01002878posix_flistdir(PyObject *self, PyObject *args)
Antoine Pitrou8250e232011-02-25 23:41:16 +00002879{
2880 PyObject *d, *v;
2881 DIR *dirp;
2882 struct dirent *ep;
2883 int fd;
2884
2885 errno = 0;
Charles-François Natali77940902012-02-06 19:54:48 +01002886 if (!PyArg_ParseTuple(args, "i:flistdir", &fd))
Antoine Pitrou8250e232011-02-25 23:41:16 +00002887 return NULL;
Charles-François Natali76961fa2012-01-10 20:25:09 +01002888 /* closedir() closes the FD, so we duplicate it */
2889 fd = dup(fd);
2890 if (fd < 0)
2891 return posix_error();
Antoine Pitrou8250e232011-02-25 23:41:16 +00002892 Py_BEGIN_ALLOW_THREADS
2893 dirp = fdopendir(fd);
2894 Py_END_ALLOW_THREADS
2895 if (dirp == NULL) {
2896 close(fd);
2897 return posix_error();
2898 }
2899 if ((d = PyList_New(0)) == NULL) {
2900 Py_BEGIN_ALLOW_THREADS
2901 closedir(dirp);
2902 Py_END_ALLOW_THREADS
2903 return NULL;
2904 }
2905 for (;;) {
2906 errno = 0;
2907 Py_BEGIN_ALLOW_THREADS
2908 ep = readdir(dirp);
2909 Py_END_ALLOW_THREADS
2910 if (ep == NULL) {
2911 if (errno == 0) {
2912 break;
2913 } else {
2914 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002915 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002916 closedir(dirp);
2917 Py_END_ALLOW_THREADS
2918 Py_DECREF(d);
2919 return posix_error();
2920 }
2921 }
2922 if (ep->d_name[0] == '.' &&
2923 (NAMLEN(ep) == 1 ||
2924 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2925 continue;
2926 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2927 if (v == NULL) {
2928 Py_CLEAR(d);
2929 break;
2930 }
2931 if (PyList_Append(d, v) != 0) {
2932 Py_DECREF(v);
2933 Py_CLEAR(d);
2934 break;
2935 }
2936 Py_DECREF(v);
2937 }
2938 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002939 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002940 closedir(dirp);
2941 Py_END_ALLOW_THREADS
2942
2943 return d;
2944}
2945#endif
2946
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002947#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002948/* A helper function for abspath on win32 */
2949static PyObject *
2950posix__getfullpathname(PyObject *self, PyObject *args)
2951{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002952 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002953 char outbuf[MAX_PATH*2];
2954 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002955 PyObject *po;
2956
2957 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
2958 {
2959 wchar_t *wpath;
2960 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2961 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00002962 DWORD result;
2963 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002964
2965 wpath = PyUnicode_AsUnicode(po);
2966 if (wpath == NULL)
2967 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02002969 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02002971 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002972 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00002973 if (!woutbufp)
2974 return PyErr_NoMemory();
2975 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2976 }
2977 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01002978 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00002979 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02002980 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002981 if (woutbufp != woutbuf)
2982 free(woutbufp);
2983 return v;
2984 }
2985 /* Drop the argument parsing error as narrow strings
2986 are also valid. */
2987 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02002988
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002989 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
2990 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00002991 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002992 if (win32_warn_bytes_api())
2993 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02002994 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00002995 outbuf, &temp)) {
2996 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002997 return NULL;
2998 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002999 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3000 return PyUnicode_Decode(outbuf, strlen(outbuf),
3001 Py_FileSystemDefaultEncoding, NULL);
3002 }
3003 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003004} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003005
Brian Curtind25aef52011-06-13 15:16:04 -05003006
Brian Curtinf5e76d02010-11-24 13:14:05 +00003007
Brian Curtind40e6f72010-07-08 21:39:08 +00003008/* A helper function for samepath on windows */
3009static PyObject *
3010posix__getfinalpathname(PyObject *self, PyObject *args)
3011{
3012 HANDLE hFile;
3013 int buf_size;
3014 wchar_t *target_path;
3015 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003016 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003017 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003018
Victor Stinnereb5657a2011-09-30 01:44:27 +02003019 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003020 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003021 path = PyUnicode_AsUnicode(po);
3022 if (path == NULL)
3023 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003024
3025 if(!check_GetFinalPathNameByHandle()) {
3026 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3027 NotImplementedError. */
3028 return PyErr_Format(PyExc_NotImplementedError,
3029 "GetFinalPathNameByHandle not available on this platform");
3030 }
3031
3032 hFile = CreateFileW(
3033 path,
3034 0, /* desired access */
3035 0, /* share mode */
3036 NULL, /* security attributes */
3037 OPEN_EXISTING,
3038 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3039 FILE_FLAG_BACKUP_SEMANTICS,
3040 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003041
Victor Stinnereb5657a2011-09-30 01:44:27 +02003042 if(hFile == INVALID_HANDLE_VALUE)
3043 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003044
3045 /* We have a good handle to the target, use it to determine the
3046 target path name. */
3047 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3048
3049 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003050 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003051
3052 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3053 if(!target_path)
3054 return PyErr_NoMemory();
3055
3056 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3057 buf_size, VOLUME_NAME_DOS);
3058 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003059 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003060
3061 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003062 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003063
3064 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003065 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003066 free(target_path);
3067 return result;
3068
3069} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003070
3071static PyObject *
3072posix__getfileinformation(PyObject *self, PyObject *args)
3073{
3074 HANDLE hFile;
3075 BY_HANDLE_FILE_INFORMATION info;
3076 int fd;
3077
3078 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3079 return NULL;
3080
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003081 if (!_PyVerify_fd(fd))
3082 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003083
3084 hFile = (HANDLE)_get_osfhandle(fd);
3085 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003086 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003087
3088 if (!GetFileInformationByHandle(hFile, &info))
3089 return win32_error("_getfileinformation", NULL);
3090
3091 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3092 info.nFileIndexHigh,
3093 info.nFileIndexLow);
3094}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003095
Brian Curtin95d028f2011-06-09 09:10:38 -05003096PyDoc_STRVAR(posix__isdir__doc__,
3097"Return true if the pathname refers to an existing directory.");
3098
Brian Curtin9c669cc2011-06-08 18:17:18 -05003099static PyObject *
3100posix__isdir(PyObject *self, PyObject *args)
3101{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003102 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003103 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003104 DWORD attributes;
3105
3106 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003107 wchar_t *wpath = PyUnicode_AsUnicode(po);
3108 if (wpath == NULL)
3109 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003110
3111 attributes = GetFileAttributesW(wpath);
3112 if (attributes == INVALID_FILE_ATTRIBUTES)
3113 Py_RETURN_FALSE;
3114 goto check;
3115 }
3116 /* Drop the argument parsing error as narrow strings
3117 are also valid. */
3118 PyErr_Clear();
3119
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003120 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003121 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003122 if (win32_warn_bytes_api())
3123 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003124 attributes = GetFileAttributesA(path);
3125 if (attributes == INVALID_FILE_ATTRIBUTES)
3126 Py_RETURN_FALSE;
3127
3128check:
3129 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3130 Py_RETURN_TRUE;
3131 else
3132 Py_RETURN_FALSE;
3133}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003134#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003136PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003137"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003138Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003139
Barry Warsaw53699e91996-12-10 23:23:01 +00003140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003141posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003142{
Victor Stinner8c62be82010-05-06 00:08:46 +00003143 int res;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003144 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003145 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003146
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003147#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003148 PyObject *po;
3149 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode))
3150 {
3151 wchar_t *wpath = PyUnicode_AsUnicode(po);
3152 if (wpath == NULL)
3153 return NULL;
3154
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003156 res = CreateDirectoryW(wpath, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003157 Py_END_ALLOW_THREADS
3158 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003159 return win32_error_object("mkdir", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003160 Py_INCREF(Py_None);
3161 return Py_None;
3162 }
3163 /* Drop the argument parsing error as narrow strings
3164 are also valid. */
3165 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003166 if (!PyArg_ParseTuple(args, "y|i:mkdir", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00003167 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003168 if (win32_warn_bytes_api())
3169 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003170 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 res = CreateDirectoryA(path, NULL);
3172 Py_END_ALLOW_THREADS
3173 if (!res) {
3174 win32_error("mkdir", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003175 return NULL;
3176 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 Py_INCREF(Py_None);
3178 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003179#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003180 PyObject *opath;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003181
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3183 PyUnicode_FSConverter, &opath, &mode))
3184 return NULL;
3185 path = PyBytes_AsString(opath);
3186 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00003187#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00003188 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003189#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003190 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003191#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 Py_END_ALLOW_THREADS
3193 if (res < 0)
3194 return posix_error_with_allocated_filename(opath);
3195 Py_DECREF(opath);
3196 Py_INCREF(Py_None);
3197 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003198#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003199}
3200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003201
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003202/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3203#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003204#include <sys/resource.h>
3205#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003206
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003207
3208#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003209PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003210"nice(inc) -> new_priority\n\n\
3211Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003212
Barry Warsaw53699e91996-12-10 23:23:01 +00003213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003214posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003215{
Victor Stinner8c62be82010-05-06 00:08:46 +00003216 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003217
Victor Stinner8c62be82010-05-06 00:08:46 +00003218 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3219 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003220
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 /* There are two flavours of 'nice': one that returns the new
3222 priority (as required by almost all standards out there) and the
3223 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3224 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003225
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 If we are of the nice family that returns the new priority, we
3227 need to clear errno before the call, and check if errno is filled
3228 before calling posix_error() on a returnvalue of -1, because the
3229 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003230
Victor Stinner8c62be82010-05-06 00:08:46 +00003231 errno = 0;
3232 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003233#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 if (value == 0)
3235 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003236#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 if (value == -1 && errno != 0)
3238 /* either nice() or getpriority() returned an error */
3239 return posix_error();
3240 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003241}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003242#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003243
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003244
3245#ifdef HAVE_GETPRIORITY
3246PyDoc_STRVAR(posix_getpriority__doc__,
3247"getpriority(which, who) -> current_priority\n\n\
3248Get program scheduling priority.");
3249
3250static PyObject *
3251posix_getpriority(PyObject *self, PyObject *args)
3252{
3253 int which, who, retval;
3254
3255 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3256 return NULL;
3257 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003258 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003259 if (errno != 0)
3260 return posix_error();
3261 return PyLong_FromLong((long)retval);
3262}
3263#endif /* HAVE_GETPRIORITY */
3264
3265
3266#ifdef HAVE_SETPRIORITY
3267PyDoc_STRVAR(posix_setpriority__doc__,
3268"setpriority(which, who, prio) -> None\n\n\
3269Set program scheduling priority.");
3270
3271static PyObject *
3272posix_setpriority(PyObject *self, PyObject *args)
3273{
3274 int which, who, prio, retval;
3275
3276 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3277 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003278 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003279 if (retval == -1)
3280 return posix_error();
3281 Py_RETURN_NONE;
3282}
3283#endif /* HAVE_SETPRIORITY */
3284
3285
Barry Warsaw53699e91996-12-10 23:23:01 +00003286static PyObject *
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003287internal_rename(PyObject *self, PyObject *args, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003288{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003289#ifdef MS_WINDOWS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003290 PyObject *src, *dst;
Victor Stinner8c62be82010-05-06 00:08:46 +00003291 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003292 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
3293 if (PyArg_ParseTuple(args,
3294 is_replace ? "UU:replace" : "UU:rename",
3295 &src, &dst))
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003296 {
3297 wchar_t *wsrc, *wdst;
3298
3299 wsrc = PyUnicode_AsUnicode(src);
3300 if (wsrc == NULL)
3301 return NULL;
3302 wdst = PyUnicode_AsUnicode(dst);
3303 if (wdst == NULL)
3304 return NULL;
3305 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003306 result = MoveFileExW(wsrc, wdst, flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003307 Py_END_ALLOW_THREADS
3308 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003309 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003310 Py_INCREF(Py_None);
3311 return Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003312 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003313 else {
3314 PyErr_Clear();
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003315 if (!PyArg_ParseTuple(args,
3316 is_replace ? "O&O&:replace" : "O&O&:rename",
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003317 PyUnicode_FSConverter, &src,
3318 PyUnicode_FSConverter, &dst))
3319 return NULL;
3320
3321 if (win32_warn_bytes_api())
3322 goto error;
3323
3324 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003325 result = MoveFileExA(PyBytes_AS_STRING(src),
3326 PyBytes_AS_STRING(dst), flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003327 Py_END_ALLOW_THREADS
3328
3329 Py_XDECREF(src);
3330 Py_XDECREF(dst);
3331
3332 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003333 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003334 Py_INCREF(Py_None);
3335 return Py_None;
3336
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003337error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003338 Py_XDECREF(src);
3339 Py_XDECREF(dst);
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003341 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003342#else
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003343 return posix_2str(args,
3344 is_replace ? "O&O&:replace" : "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003345#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003346}
3347
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003348PyDoc_STRVAR(posix_rename__doc__,
3349"rename(old, new)\n\n\
3350Rename a file or directory.");
3351
3352static PyObject *
3353posix_rename(PyObject *self, PyObject *args)
3354{
3355 return internal_rename(self, args, 0);
3356}
3357
3358PyDoc_STRVAR(posix_replace__doc__,
3359"replace(old, new)\n\n\
3360Rename a file or directory, overwriting the destination.");
3361
3362static PyObject *
3363posix_replace(PyObject *self, PyObject *args)
3364{
3365 return internal_rename(self, args, 1);
3366}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003368PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003369"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003370Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003371
Barry Warsaw53699e91996-12-10 23:23:01 +00003372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003373posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003374{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003375#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003376 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003377#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003378 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003379#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003380}
3381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003383PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003384"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003385Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003386
Barry Warsaw53699e91996-12-10 23:23:01 +00003387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003388posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003389{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003390#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00003391 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003392#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003393 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003394#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003395}
3396
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003397
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003398#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003399PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003400"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003401Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003402
Barry Warsaw53699e91996-12-10 23:23:01 +00003403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003404posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003405{
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003407#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 wchar_t *command;
3409 if (!PyArg_ParseTuple(args, "u:system", &command))
3410 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003411
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 Py_BEGIN_ALLOW_THREADS
3413 sts = _wsystem(command);
3414 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003415#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 PyObject *command_obj;
3417 char *command;
3418 if (!PyArg_ParseTuple(args, "O&:system",
3419 PyUnicode_FSConverter, &command_obj))
3420 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003421
Victor Stinner8c62be82010-05-06 00:08:46 +00003422 command = PyBytes_AsString(command_obj);
3423 Py_BEGIN_ALLOW_THREADS
3424 sts = system(command);
3425 Py_END_ALLOW_THREADS
3426 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003427#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003429}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003430#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003431
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003432
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003433PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003434"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003435Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003436
Barry Warsaw53699e91996-12-10 23:23:01 +00003437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003438posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003439{
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 int i;
3441 if (!PyArg_ParseTuple(args, "i:umask", &i))
3442 return NULL;
3443 i = (int)umask(i);
3444 if (i < 0)
3445 return posix_error();
3446 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003447}
3448
Brian Curtind40e6f72010-07-08 21:39:08 +00003449#ifdef MS_WINDOWS
3450
3451/* override the default DeleteFileW behavior so that directory
3452symlinks can be removed with this function, the same as with
3453Unix symlinks */
3454BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3455{
3456 WIN32_FILE_ATTRIBUTE_DATA info;
3457 WIN32_FIND_DATAW find_data;
3458 HANDLE find_data_handle;
3459 int is_directory = 0;
3460 int is_link = 0;
3461
3462 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3463 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003464
Brian Curtind40e6f72010-07-08 21:39:08 +00003465 /* Get WIN32_FIND_DATA structure for the path to determine if
3466 it is a symlink */
3467 if(is_directory &&
3468 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3469 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3470
3471 if(find_data_handle != INVALID_HANDLE_VALUE) {
3472 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3473 FindClose(find_data_handle);
3474 }
3475 }
3476 }
3477
3478 if (is_directory && is_link)
3479 return RemoveDirectoryW(lpFileName);
3480
3481 return DeleteFileW(lpFileName);
3482}
3483#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003485PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003486"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003487Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003489PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003490"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003491Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003492
Barry Warsaw53699e91996-12-10 23:23:01 +00003493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003494posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003495{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003496#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003497 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3498 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003499#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003501#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003502}
3503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003504
Guido van Rossumb6775db1994-08-01 11:34:53 +00003505#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003506PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003507"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003508Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003509
Barry Warsaw53699e91996-12-10 23:23:01 +00003510static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003511posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003512{
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 struct utsname u;
3514 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003515
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 Py_BEGIN_ALLOW_THREADS
3517 res = uname(&u);
3518 Py_END_ALLOW_THREADS
3519 if (res < 0)
3520 return posix_error();
3521 return Py_BuildValue("(sssss)",
3522 u.sysname,
3523 u.nodename,
3524 u.release,
3525 u.version,
3526 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003527}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003528#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003529
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003530
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003531static int
Victor Stinnera2f7c002012-02-08 03:36:25 +01003532extract_time(PyObject *t, time_t* sec, long* nsec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003533{
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003534 time_t intval;
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 if (PyFloat_Check(t)) {
Victor Stinnera2f7c002012-02-08 03:36:25 +01003536 double d = PyFloat_AsDouble(t);
3537 double mod;
3538 *sec = (time_t)d;
3539 mod = fmod(d, 1.0);
3540 mod *= 1e9;
3541 *nsec = (long)mod;
3542 printf("%g => (%u, %li)\n", d, *sec, *nsec);
Martin v. Löwis076b2092002-09-10 15:04:41 +00003543 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 }
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003545#if SIZEOF_TIME_T > SIZEOF_LONG
3546 intval = PyLong_AsUnsignedLongLongMask(t);
3547#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003549#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 if (intval == -1 && PyErr_Occurred())
3551 return -1;
3552 *sec = intval;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003553 *nsec = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003554 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003555}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003556
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003557PyDoc_STRVAR(posix_utime__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003558"utime(path[, (atime, mtime)])\n\
3559Set the access and modified time of the file to the given values.\n\
3560If no second argument is used, set the access and modified times to\n\
3561the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003562
Barry Warsaw53699e91996-12-10 23:23:01 +00003563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003564posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003565{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003566#ifdef MS_WINDOWS
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003567 PyObject *arg = Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003568 PyObject *obwpath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 wchar_t *wpath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003570 const char *apath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003572 time_t atimesec, mtimesec;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003573 long ansec, mnsec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 FILETIME atime, mtime;
3575 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003576
Brian Curtin52fbea12011-11-06 13:41:17 -06003577 if (PyArg_ParseTuple(args, "U|O:utime", &obwpath, &arg)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003578 wpath = PyUnicode_AsUnicode(obwpath);
3579 if (wpath == NULL)
3580 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003581 Py_BEGIN_ALLOW_THREADS
3582 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3583 NULL, OPEN_EXISTING,
3584 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3585 Py_END_ALLOW_THREADS
3586 if (hFile == INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003587 return win32_error_object("utime", obwpath);
3588 }
3589 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 /* Drop the argument parsing error as narrow strings
3591 are also valid. */
3592 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003593
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003594 if (!PyArg_ParseTuple(args, "y|O:utime", &apath, &arg))
3595 return NULL;
3596 if (win32_warn_bytes_api())
Victor Stinner8c62be82010-05-06 00:08:46 +00003597 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003598
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 Py_BEGIN_ALLOW_THREADS
3600 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3601 NULL, OPEN_EXISTING,
3602 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3603 Py_END_ALLOW_THREADS
3604 if (hFile == INVALID_HANDLE_VALUE) {
3605 win32_error("utime", apath);
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 return NULL;
3607 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003608 }
3609
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003610 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003611 SYSTEMTIME now;
3612 GetSystemTime(&now);
3613 if (!SystemTimeToFileTime(&now, &mtime) ||
3614 !SystemTimeToFileTime(&now, &atime)) {
3615 win32_error("utime", NULL);
3616 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003617 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 }
3619 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3620 PyErr_SetString(PyExc_TypeError,
3621 "utime() arg 2 must be a tuple (atime, mtime)");
3622 goto done;
3623 }
3624 else {
3625 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003626 &atimesec, &ansec) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 goto done;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003628 time_t_to_FILE_TIME(atimesec, ansec, &atime);
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003630 &mtimesec, &mnsec) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00003631 goto done;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003632 time_t_to_FILE_TIME(mtimesec, mnsec, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 }
3634 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3635 /* Avoid putting the file name into the error here,
3636 as that may confuse the user into believing that
3637 something is wrong with the file, when it also
3638 could be the time stamp that gives a problem. */
3639 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003640 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003641 }
3642 Py_INCREF(Py_None);
3643 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003644done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 CloseHandle(hFile);
3646 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003647#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003648
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 PyObject *opath;
3650 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003651 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003652 long ansec, mnsec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 int res;
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003654 PyObject* arg = Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003655
Brian Curtin52fbea12011-11-06 13:41:17 -06003656 if (!PyArg_ParseTuple(args, "O&|O:utime",
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 PyUnicode_FSConverter, &opath, &arg))
3658 return NULL;
3659 path = PyBytes_AsString(opath);
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003660 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 /* optional time values not given */
3662 Py_BEGIN_ALLOW_THREADS
3663 res = utime(path, NULL);
3664 Py_END_ALLOW_THREADS
3665 }
3666 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3667 PyErr_SetString(PyExc_TypeError,
3668 "utime() arg 2 must be a tuple (atime, mtime)");
3669 Py_DECREF(opath);
3670 return NULL;
3671 }
3672 else {
3673 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003674 &atime, &ansec) == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003675 Py_DECREF(opath);
3676 return NULL;
3677 }
3678 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003679 &mtime, &mnsec) == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 Py_DECREF(opath);
3681 return NULL;
3682 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003683
3684 Py_BEGIN_ALLOW_THREADS
3685 {
3686#ifdef HAVE_UTIMENSAT
3687 struct timespec buf[2];
3688 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003689 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003690 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003691 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003692 res = utimensat(AT_FDCWD, path, buf, 0);
3693#elif defined(HAVE_UTIMES)
3694 struct timeval buf[2];
3695 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003696 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003697 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003698 buf[1].tv_usec = mnsec / 1000;
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 res = utimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003700#elif defined(HAVE_UTIME_H)
3701 /* XXX should define struct utimbuf instead, above */
3702 struct utimbuf buf;
3703 buf.actime = atime;
3704 buf.modtime = mtime;
3705 res = utime(path, &buf);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003706#else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003707 time_t buf[2];
3708 buf[0] = atime;
3709 buf[1] = mtime;
3710 res = utime(path, buf);
3711#endif
3712 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003713 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 }
3715 if (res < 0) {
3716 return posix_error_with_allocated_filename(opath);
3717 }
3718 Py_DECREF(opath);
3719 Py_INCREF(Py_None);
3720 return Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003721#undef UTIME_EXTRACT
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003722#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003723}
3724
Ross Lagerwall7807c352011-03-17 20:20:30 +02003725#ifdef HAVE_FUTIMES
3726PyDoc_STRVAR(posix_futimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003727"futimes(fd[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003728Set the access and modified time of the file specified by the file\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003729descriptor fd to the given values. If no second argument is used, set the\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003730access and modified times to the current time.");
3731
3732static PyObject *
3733posix_futimes(PyObject *self, PyObject *args)
3734{
3735 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003736 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003737 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003738 long ansec, mnsec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003739
Brian Curtinc1b65d12011-11-07 14:18:54 -06003740 if (!PyArg_ParseTuple(args, "i|O:futimes", &fd, &arg))
Ross Lagerwall7807c352011-03-17 20:20:30 +02003741 return NULL;
3742
3743 if (arg == Py_None) {
3744 /* optional time values not given */
3745 Py_BEGIN_ALLOW_THREADS
3746 res = futimes(fd, NULL);
3747 Py_END_ALLOW_THREADS
3748 }
3749 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3750 PyErr_SetString(PyExc_TypeError,
3751 "futimes() arg 2 must be a tuple (atime, mtime)");
3752 return NULL;
3753 }
3754 else {
3755 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003756 &atime, &ansec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003757 return NULL;
3758 }
3759 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003760 &mtime, &mnsec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003761 return NULL;
3762 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003763 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003764 {
3765#ifdef HAVE_FUTIMENS
3766 struct timespec buf[2];
3767 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003768 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003769 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003770 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003771 res = futimens(fd, buf);
3772#else
3773 struct timeval buf[2];
3774 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003775 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003776 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003777 buf[1].tv_usec = mnsec / 1000;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003778 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003779#endif
3780 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003781 Py_END_ALLOW_THREADS
3782 }
3783 if (res < 0)
3784 return posix_error();
3785 Py_RETURN_NONE;
3786}
3787#endif
3788
3789#ifdef HAVE_LUTIMES
3790PyDoc_STRVAR(posix_lutimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003791"lutimes(path[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003792Like utime(), but if path is a symbolic link, it is not dereferenced.");
3793
3794static PyObject *
3795posix_lutimes(PyObject *self, PyObject *args)
3796{
Brian Curtinc1b65d12011-11-07 14:18:54 -06003797 PyObject *opath;
3798 PyObject *arg = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003799 const char *path;
3800 int res;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003801 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003802 long ansec, mnsec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003803
Brian Curtinc1b65d12011-11-07 14:18:54 -06003804 if (!PyArg_ParseTuple(args, "O&|O:lutimes",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003805 PyUnicode_FSConverter, &opath, &arg))
3806 return NULL;
3807 path = PyBytes_AsString(opath);
3808 if (arg == Py_None) {
3809 /* optional time values not given */
3810 Py_BEGIN_ALLOW_THREADS
3811 res = lutimes(path, NULL);
3812 Py_END_ALLOW_THREADS
3813 }
3814 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3815 PyErr_SetString(PyExc_TypeError,
3816 "lutimes() arg 2 must be a tuple (atime, mtime)");
3817 Py_DECREF(opath);
3818 return NULL;
3819 }
3820 else {
3821 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003822 &atime, &ansec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003823 Py_DECREF(opath);
3824 return NULL;
3825 }
3826 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003827 &mtime, &mnsec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003828 Py_DECREF(opath);
3829 return NULL;
3830 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003831 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003832 {
3833#ifdef HAVE_UTIMENSAT
3834 struct timespec buf[2];
3835 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003836 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003837 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003838 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003839 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3840#else
3841 struct timeval buf[2];
3842 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003843 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003844 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003845 buf[1].tv_usec = mnsec / 1000;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003846 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003847#endif
3848 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003849 Py_END_ALLOW_THREADS
3850 }
3851 Py_DECREF(opath);
3852 if (res < 0)
3853 return posix_error();
3854 Py_RETURN_NONE;
3855}
3856#endif
3857
3858#ifdef HAVE_FUTIMENS
3859PyDoc_STRVAR(posix_futimens__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003860"futimens(fd[, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003861Updates the timestamps of a file specified by the file descriptor fd, with\n\
3862nanosecond precision.\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003863If no second argument is given, set atime and mtime to the current time.\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003864If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
3865current time.\n\
3866If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
3867
3868static PyObject *
3869posix_futimens(PyObject *self, PyObject *args)
3870{
3871 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003872 PyObject *atime = Py_None;
3873 PyObject *mtime = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003874 struct timespec buf[2];
3875
Brian Curtinc1b65d12011-11-07 14:18:54 -06003876 if (!PyArg_ParseTuple(args, "i|OO:futimens",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003877 &fd, &atime, &mtime))
3878 return NULL;
3879 if (atime == Py_None && mtime == Py_None) {
3880 /* optional time values not given */
3881 Py_BEGIN_ALLOW_THREADS
3882 res = futimens(fd, NULL);
3883 Py_END_ALLOW_THREADS
3884 }
3885 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
3886 PyErr_SetString(PyExc_TypeError,
3887 "futimens() arg 2 must be a tuple (atime_sec, atime_nsec)");
3888 return NULL;
3889 }
3890 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
3891 PyErr_SetString(PyExc_TypeError,
3892 "futimens() arg 3 must be a tuple (mtime_sec, mtime_nsec)");
3893 return NULL;
3894 }
3895 else {
3896 if (!PyArg_ParseTuple(atime, "ll:futimens",
3897 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
3898 return NULL;
3899 }
3900 if (!PyArg_ParseTuple(mtime, "ll:futimens",
3901 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
3902 return NULL;
3903 }
3904 Py_BEGIN_ALLOW_THREADS
3905 res = futimens(fd, buf);
3906 Py_END_ALLOW_THREADS
3907 }
3908 if (res < 0)
3909 return posix_error();
3910 Py_RETURN_NONE;
3911}
3912#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003913
Guido van Rossum3b066191991-06-04 19:40:25 +00003914/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003915
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003916PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003917"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003918Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003919
Barry Warsaw53699e91996-12-10 23:23:01 +00003920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003921posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003922{
Victor Stinner8c62be82010-05-06 00:08:46 +00003923 int sts;
3924 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3925 return NULL;
3926 _exit(sts);
3927 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003928}
3929
Martin v. Löwis114619e2002-10-07 06:44:21 +00003930#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3931static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003932free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003933{
Victor Stinner8c62be82010-05-06 00:08:46 +00003934 Py_ssize_t i;
3935 for (i = 0; i < count; i++)
3936 PyMem_Free(array[i]);
3937 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003938}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003939
Antoine Pitrou69f71142009-05-24 21:25:49 +00003940static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003941int fsconvert_strdup(PyObject *o, char**out)
3942{
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 PyObject *bytes;
3944 Py_ssize_t size;
3945 if (!PyUnicode_FSConverter(o, &bytes))
3946 return 0;
3947 size = PyBytes_GET_SIZE(bytes);
3948 *out = PyMem_Malloc(size+1);
3949 if (!*out)
3950 return 0;
3951 memcpy(*out, PyBytes_AsString(bytes), size+1);
3952 Py_DECREF(bytes);
3953 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003954}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003955#endif
3956
Ross Lagerwall7807c352011-03-17 20:20:30 +02003957#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00003958static char**
3959parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3960{
Victor Stinner8c62be82010-05-06 00:08:46 +00003961 char **envlist;
3962 Py_ssize_t i, pos, envc;
3963 PyObject *keys=NULL, *vals=NULL;
3964 PyObject *key, *val, *key2, *val2;
3965 char *p, *k, *v;
3966 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003967
Victor Stinner8c62be82010-05-06 00:08:46 +00003968 i = PyMapping_Size(env);
3969 if (i < 0)
3970 return NULL;
3971 envlist = PyMem_NEW(char *, i + 1);
3972 if (envlist == NULL) {
3973 PyErr_NoMemory();
3974 return NULL;
3975 }
3976 envc = 0;
3977 keys = PyMapping_Keys(env);
3978 vals = PyMapping_Values(env);
3979 if (!keys || !vals)
3980 goto error;
3981 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3982 PyErr_Format(PyExc_TypeError,
3983 "env.keys() or env.values() is not a list");
3984 goto error;
3985 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003986
Victor Stinner8c62be82010-05-06 00:08:46 +00003987 for (pos = 0; pos < i; pos++) {
3988 key = PyList_GetItem(keys, pos);
3989 val = PyList_GetItem(vals, pos);
3990 if (!key || !val)
3991 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003992
Victor Stinner8c62be82010-05-06 00:08:46 +00003993 if (PyUnicode_FSConverter(key, &key2) == 0)
3994 goto error;
3995 if (PyUnicode_FSConverter(val, &val2) == 0) {
3996 Py_DECREF(key2);
3997 goto error;
3998 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003999
4000#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004001 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4002 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004003#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 k = PyBytes_AsString(key2);
4005 v = PyBytes_AsString(val2);
4006 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004007
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 p = PyMem_NEW(char, len);
4009 if (p == NULL) {
4010 PyErr_NoMemory();
4011 Py_DECREF(key2);
4012 Py_DECREF(val2);
4013 goto error;
4014 }
4015 PyOS_snprintf(p, len, "%s=%s", k, v);
4016 envlist[envc++] = p;
4017 Py_DECREF(key2);
4018 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004019#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004020 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004021#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004022 }
4023 Py_DECREF(vals);
4024 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004025
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 envlist[envc] = 0;
4027 *envc_ptr = envc;
4028 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004029
4030error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004031 Py_XDECREF(keys);
4032 Py_XDECREF(vals);
4033 while (--envc >= 0)
4034 PyMem_DEL(envlist[envc]);
4035 PyMem_DEL(envlist);
4036 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004037}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004038
Ross Lagerwall7807c352011-03-17 20:20:30 +02004039static char**
4040parse_arglist(PyObject* argv, Py_ssize_t *argc)
4041{
4042 int i;
4043 char **argvlist = PyMem_NEW(char *, *argc+1);
4044 if (argvlist == NULL) {
4045 PyErr_NoMemory();
4046 return NULL;
4047 }
4048 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004049 PyObject* item = PySequence_ITEM(argv, i);
4050 if (item == NULL)
4051 goto fail;
4052 if (!fsconvert_strdup(item, &argvlist[i])) {
4053 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004054 goto fail;
4055 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004056 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004057 }
4058 argvlist[*argc] = NULL;
4059 return argvlist;
4060fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004061 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004062 free_string_array(argvlist, *argc);
4063 return NULL;
4064}
4065#endif
4066
4067#ifdef HAVE_EXECV
4068PyDoc_STRVAR(posix_execv__doc__,
4069"execv(path, args)\n\n\
4070Execute an executable path with arguments, replacing current process.\n\
4071\n\
4072 path: path of executable file\n\
4073 args: tuple or list of strings");
4074
4075static PyObject *
4076posix_execv(PyObject *self, PyObject *args)
4077{
4078 PyObject *opath;
4079 char *path;
4080 PyObject *argv;
4081 char **argvlist;
4082 Py_ssize_t argc;
4083
4084 /* execv has two arguments: (path, argv), where
4085 argv is a list or tuple of strings. */
4086
4087 if (!PyArg_ParseTuple(args, "O&O:execv",
4088 PyUnicode_FSConverter,
4089 &opath, &argv))
4090 return NULL;
4091 path = PyBytes_AsString(opath);
4092 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4093 PyErr_SetString(PyExc_TypeError,
4094 "execv() arg 2 must be a tuple or list");
4095 Py_DECREF(opath);
4096 return NULL;
4097 }
4098 argc = PySequence_Size(argv);
4099 if (argc < 1) {
4100 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4101 Py_DECREF(opath);
4102 return NULL;
4103 }
4104
4105 argvlist = parse_arglist(argv, &argc);
4106 if (argvlist == NULL) {
4107 Py_DECREF(opath);
4108 return NULL;
4109 }
4110
4111 execv(path, argvlist);
4112
4113 /* If we get here it's definitely an error */
4114
4115 free_string_array(argvlist, argc);
4116 Py_DECREF(opath);
4117 return posix_error();
4118}
4119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004120PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004121"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004122Execute a path with arguments and environment, replacing current process.\n\
4123\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004124 path: path of executable file\n\
4125 args: tuple or list of arguments\n\
4126 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004127
Barry Warsaw53699e91996-12-10 23:23:01 +00004128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004129posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004130{
Victor Stinner8c62be82010-05-06 00:08:46 +00004131 PyObject *opath;
4132 char *path;
4133 PyObject *argv, *env;
4134 char **argvlist;
4135 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004136 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004137
Victor Stinner8c62be82010-05-06 00:08:46 +00004138 /* execve has three arguments: (path, argv, env), where
4139 argv is a list or tuple of strings and env is a dictionary
4140 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004141
Victor Stinner8c62be82010-05-06 00:08:46 +00004142 if (!PyArg_ParseTuple(args, "O&OO:execve",
4143 PyUnicode_FSConverter,
4144 &opath, &argv, &env))
4145 return NULL;
4146 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004147 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004148 PyErr_SetString(PyExc_TypeError,
4149 "execve() arg 2 must be a tuple or list");
4150 goto fail_0;
4151 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004152 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004153 if (!PyMapping_Check(env)) {
4154 PyErr_SetString(PyExc_TypeError,
4155 "execve() arg 3 must be a mapping object");
4156 goto fail_0;
4157 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004158
Ross Lagerwall7807c352011-03-17 20:20:30 +02004159 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004160 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004161 goto fail_0;
4162 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004163
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 envlist = parse_envlist(env, &envc);
4165 if (envlist == NULL)
4166 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004167
Victor Stinner8c62be82010-05-06 00:08:46 +00004168 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004169
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004171
Victor Stinner8c62be82010-05-06 00:08:46 +00004172 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004173
Victor Stinner8c62be82010-05-06 00:08:46 +00004174 while (--envc >= 0)
4175 PyMem_DEL(envlist[envc]);
4176 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004177 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004178 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004179 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 Py_DECREF(opath);
4181 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004182}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004183#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004184
Ross Lagerwall7807c352011-03-17 20:20:30 +02004185#ifdef HAVE_FEXECVE
4186PyDoc_STRVAR(posix_fexecve__doc__,
4187"fexecve(fd, args, env)\n\n\
4188Execute the program specified by a file descriptor with arguments and\n\
4189environment, replacing the current process.\n\
4190\n\
4191 fd: file descriptor of executable\n\
4192 args: tuple or list of arguments\n\
4193 env: dictionary of strings mapping to strings");
4194
4195static PyObject *
4196posix_fexecve(PyObject *self, PyObject *args)
4197{
4198 int fd;
4199 PyObject *argv, *env;
4200 char **argvlist;
4201 char **envlist;
4202 Py_ssize_t argc, envc;
4203
4204 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4205 &fd, &argv, &env))
4206 return NULL;
4207 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4208 PyErr_SetString(PyExc_TypeError,
4209 "fexecve() arg 2 must be a tuple or list");
4210 return NULL;
4211 }
4212 argc = PySequence_Size(argv);
4213 if (!PyMapping_Check(env)) {
4214 PyErr_SetString(PyExc_TypeError,
4215 "fexecve() arg 3 must be a mapping object");
4216 return NULL;
4217 }
4218
4219 argvlist = parse_arglist(argv, &argc);
4220 if (argvlist == NULL)
4221 return NULL;
4222
4223 envlist = parse_envlist(env, &envc);
4224 if (envlist == NULL)
4225 goto fail;
4226
4227 fexecve(fd, argvlist, envlist);
4228
4229 /* If we get here it's definitely an error */
4230
4231 (void) posix_error();
4232
4233 while (--envc >= 0)
4234 PyMem_DEL(envlist[envc]);
4235 PyMem_DEL(envlist);
4236 fail:
4237 free_string_array(argvlist, argc);
4238 return NULL;
4239}
4240#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004241
Guido van Rossuma1065681999-01-25 23:20:23 +00004242#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004243PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004244"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004245Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004246\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004247 mode: mode of process creation\n\
4248 path: path of executable file\n\
4249 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004250
4251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004252posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004253{
Victor Stinner8c62be82010-05-06 00:08:46 +00004254 PyObject *opath;
4255 char *path;
4256 PyObject *argv;
4257 char **argvlist;
4258 int mode, i;
4259 Py_ssize_t argc;
4260 Py_intptr_t spawnval;
4261 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004262
Victor Stinner8c62be82010-05-06 00:08:46 +00004263 /* spawnv has three arguments: (mode, path, argv), where
4264 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004265
Victor Stinner8c62be82010-05-06 00:08:46 +00004266 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4267 PyUnicode_FSConverter,
4268 &opath, &argv))
4269 return NULL;
4270 path = PyBytes_AsString(opath);
4271 if (PyList_Check(argv)) {
4272 argc = PyList_Size(argv);
4273 getitem = PyList_GetItem;
4274 }
4275 else if (PyTuple_Check(argv)) {
4276 argc = PyTuple_Size(argv);
4277 getitem = PyTuple_GetItem;
4278 }
4279 else {
4280 PyErr_SetString(PyExc_TypeError,
4281 "spawnv() arg 2 must be a tuple or list");
4282 Py_DECREF(opath);
4283 return NULL;
4284 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004285
Victor Stinner8c62be82010-05-06 00:08:46 +00004286 argvlist = PyMem_NEW(char *, argc+1);
4287 if (argvlist == NULL) {
4288 Py_DECREF(opath);
4289 return PyErr_NoMemory();
4290 }
4291 for (i = 0; i < argc; i++) {
4292 if (!fsconvert_strdup((*getitem)(argv, i),
4293 &argvlist[i])) {
4294 free_string_array(argvlist, i);
4295 PyErr_SetString(
4296 PyExc_TypeError,
4297 "spawnv() arg 2 must contain only strings");
4298 Py_DECREF(opath);
4299 return NULL;
4300 }
4301 }
4302 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004303
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004304#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004305 Py_BEGIN_ALLOW_THREADS
4306 spawnval = spawnv(mode, path, argvlist);
4307 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004308#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004309 if (mode == _OLD_P_OVERLAY)
4310 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004311
Victor Stinner8c62be82010-05-06 00:08:46 +00004312 Py_BEGIN_ALLOW_THREADS
4313 spawnval = _spawnv(mode, path, argvlist);
4314 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004315#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004316
Victor Stinner8c62be82010-05-06 00:08:46 +00004317 free_string_array(argvlist, argc);
4318 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004319
Victor Stinner8c62be82010-05-06 00:08:46 +00004320 if (spawnval == -1)
4321 return posix_error();
4322 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004323#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004324 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004325#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004326 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004327#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004328}
4329
4330
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004331PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004332"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004333Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004334\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004335 mode: mode of process creation\n\
4336 path: path of executable file\n\
4337 args: tuple or list of arguments\n\
4338 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004339
4340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004341posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004342{
Victor Stinner8c62be82010-05-06 00:08:46 +00004343 PyObject *opath;
4344 char *path;
4345 PyObject *argv, *env;
4346 char **argvlist;
4347 char **envlist;
4348 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004349 int mode;
4350 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004351 Py_intptr_t spawnval;
4352 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4353 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004354
Victor Stinner8c62be82010-05-06 00:08:46 +00004355 /* spawnve has four arguments: (mode, path, argv, env), where
4356 argv is a list or tuple of strings and env is a dictionary
4357 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004358
Victor Stinner8c62be82010-05-06 00:08:46 +00004359 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4360 PyUnicode_FSConverter,
4361 &opath, &argv, &env))
4362 return NULL;
4363 path = PyBytes_AsString(opath);
4364 if (PyList_Check(argv)) {
4365 argc = PyList_Size(argv);
4366 getitem = PyList_GetItem;
4367 }
4368 else if (PyTuple_Check(argv)) {
4369 argc = PyTuple_Size(argv);
4370 getitem = PyTuple_GetItem;
4371 }
4372 else {
4373 PyErr_SetString(PyExc_TypeError,
4374 "spawnve() arg 2 must be a tuple or list");
4375 goto fail_0;
4376 }
4377 if (!PyMapping_Check(env)) {
4378 PyErr_SetString(PyExc_TypeError,
4379 "spawnve() arg 3 must be a mapping object");
4380 goto fail_0;
4381 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004382
Victor Stinner8c62be82010-05-06 00:08:46 +00004383 argvlist = PyMem_NEW(char *, argc+1);
4384 if (argvlist == NULL) {
4385 PyErr_NoMemory();
4386 goto fail_0;
4387 }
4388 for (i = 0; i < argc; i++) {
4389 if (!fsconvert_strdup((*getitem)(argv, i),
4390 &argvlist[i]))
4391 {
4392 lastarg = i;
4393 goto fail_1;
4394 }
4395 }
4396 lastarg = argc;
4397 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004398
Victor Stinner8c62be82010-05-06 00:08:46 +00004399 envlist = parse_envlist(env, &envc);
4400 if (envlist == NULL)
4401 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004402
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004403#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004404 Py_BEGIN_ALLOW_THREADS
4405 spawnval = spawnve(mode, path, argvlist, envlist);
4406 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004407#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004408 if (mode == _OLD_P_OVERLAY)
4409 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004410
Victor Stinner8c62be82010-05-06 00:08:46 +00004411 Py_BEGIN_ALLOW_THREADS
4412 spawnval = _spawnve(mode, path, argvlist, envlist);
4413 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004414#endif
Tim Peters25059d32001-12-07 20:35:43 +00004415
Victor Stinner8c62be82010-05-06 00:08:46 +00004416 if (spawnval == -1)
4417 (void) posix_error();
4418 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004419#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004420 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004421#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004423#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004424
Victor Stinner8c62be82010-05-06 00:08:46 +00004425 while (--envc >= 0)
4426 PyMem_DEL(envlist[envc]);
4427 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004428 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004429 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004430 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004431 Py_DECREF(opath);
4432 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004433}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004434
4435/* OS/2 supports spawnvp & spawnvpe natively */
4436#if defined(PYOS_OS2)
4437PyDoc_STRVAR(posix_spawnvp__doc__,
4438"spawnvp(mode, file, args)\n\n\
4439Execute the program 'file' in a new process, using the environment\n\
4440search path to find the file.\n\
4441\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004442 mode: mode of process creation\n\
4443 file: executable file name\n\
4444 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004445
4446static PyObject *
4447posix_spawnvp(PyObject *self, PyObject *args)
4448{
Victor Stinner8c62be82010-05-06 00:08:46 +00004449 PyObject *opath;
4450 char *path;
4451 PyObject *argv;
4452 char **argvlist;
4453 int mode, i, argc;
4454 Py_intptr_t spawnval;
4455 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004456
Victor Stinner8c62be82010-05-06 00:08:46 +00004457 /* spawnvp has three arguments: (mode, path, argv), where
4458 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004459
Victor Stinner8c62be82010-05-06 00:08:46 +00004460 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4461 PyUnicode_FSConverter,
4462 &opath, &argv))
4463 return NULL;
4464 path = PyBytes_AsString(opath);
4465 if (PyList_Check(argv)) {
4466 argc = PyList_Size(argv);
4467 getitem = PyList_GetItem;
4468 }
4469 else if (PyTuple_Check(argv)) {
4470 argc = PyTuple_Size(argv);
4471 getitem = PyTuple_GetItem;
4472 }
4473 else {
4474 PyErr_SetString(PyExc_TypeError,
4475 "spawnvp() arg 2 must be a tuple or list");
4476 Py_DECREF(opath);
4477 return NULL;
4478 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004479
Victor Stinner8c62be82010-05-06 00:08:46 +00004480 argvlist = PyMem_NEW(char *, argc+1);
4481 if (argvlist == NULL) {
4482 Py_DECREF(opath);
4483 return PyErr_NoMemory();
4484 }
4485 for (i = 0; i < argc; i++) {
4486 if (!fsconvert_strdup((*getitem)(argv, i),
4487 &argvlist[i])) {
4488 free_string_array(argvlist, i);
4489 PyErr_SetString(
4490 PyExc_TypeError,
4491 "spawnvp() arg 2 must contain only strings");
4492 Py_DECREF(opath);
4493 return NULL;
4494 }
4495 }
4496 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004497
Victor Stinner8c62be82010-05-06 00:08:46 +00004498 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004499#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004500 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004501#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004502 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004503#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004504 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004505
Victor Stinner8c62be82010-05-06 00:08:46 +00004506 free_string_array(argvlist, argc);
4507 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004508
Victor Stinner8c62be82010-05-06 00:08:46 +00004509 if (spawnval == -1)
4510 return posix_error();
4511 else
4512 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004513}
4514
4515
4516PyDoc_STRVAR(posix_spawnvpe__doc__,
4517"spawnvpe(mode, file, args, env)\n\n\
4518Execute the program 'file' in a new process, using the environment\n\
4519search path to find the file.\n\
4520\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004521 mode: mode of process creation\n\
4522 file: executable file name\n\
4523 args: tuple or list of arguments\n\
4524 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004525
4526static PyObject *
4527posix_spawnvpe(PyObject *self, PyObject *args)
4528{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02004529 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00004530 char *path;
4531 PyObject *argv, *env;
4532 char **argvlist;
4533 char **envlist;
4534 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004535 int mode;
4536 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004537 Py_intptr_t spawnval;
4538 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4539 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004540
Victor Stinner8c62be82010-05-06 00:08:46 +00004541 /* spawnvpe has four arguments: (mode, path, argv, env), where
4542 argv is a list or tuple of strings and env is a dictionary
4543 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004544
Victor Stinner8c62be82010-05-06 00:08:46 +00004545 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4546 PyUnicode_FSConverter,
4547 &opath, &argv, &env))
4548 return NULL;
4549 path = PyBytes_AsString(opath);
4550 if (PyList_Check(argv)) {
4551 argc = PyList_Size(argv);
4552 getitem = PyList_GetItem;
4553 }
4554 else if (PyTuple_Check(argv)) {
4555 argc = PyTuple_Size(argv);
4556 getitem = PyTuple_GetItem;
4557 }
4558 else {
4559 PyErr_SetString(PyExc_TypeError,
4560 "spawnvpe() arg 2 must be a tuple or list");
4561 goto fail_0;
4562 }
4563 if (!PyMapping_Check(env)) {
4564 PyErr_SetString(PyExc_TypeError,
4565 "spawnvpe() arg 3 must be a mapping object");
4566 goto fail_0;
4567 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004568
Victor Stinner8c62be82010-05-06 00:08:46 +00004569 argvlist = PyMem_NEW(char *, argc+1);
4570 if (argvlist == NULL) {
4571 PyErr_NoMemory();
4572 goto fail_0;
4573 }
4574 for (i = 0; i < argc; i++) {
4575 if (!fsconvert_strdup((*getitem)(argv, i),
4576 &argvlist[i]))
4577 {
4578 lastarg = i;
4579 goto fail_1;
4580 }
4581 }
4582 lastarg = argc;
4583 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004584
Victor Stinner8c62be82010-05-06 00:08:46 +00004585 envlist = parse_envlist(env, &envc);
4586 if (envlist == NULL)
4587 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004588
Victor Stinner8c62be82010-05-06 00:08:46 +00004589 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004590#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004591 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004592#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004593 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004594#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004595 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004596
Victor Stinner8c62be82010-05-06 00:08:46 +00004597 if (spawnval == -1)
4598 (void) posix_error();
4599 else
4600 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004601
Victor Stinner8c62be82010-05-06 00:08:46 +00004602 while (--envc >= 0)
4603 PyMem_DEL(envlist[envc]);
4604 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004605 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004606 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004607 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004608 Py_DECREF(opath);
4609 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004610}
4611#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004612#endif /* HAVE_SPAWNV */
4613
4614
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004615#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004616PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004617"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004618Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4619\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004620Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004621
4622static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004623posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004624{
Victor Stinner8c62be82010-05-06 00:08:46 +00004625 pid_t pid;
4626 int result = 0;
4627 _PyImport_AcquireLock();
4628 pid = fork1();
4629 if (pid == 0) {
4630 /* child: this clobbers and resets the import lock. */
4631 PyOS_AfterFork();
4632 } else {
4633 /* parent: release the import lock. */
4634 result = _PyImport_ReleaseLock();
4635 }
4636 if (pid == -1)
4637 return posix_error();
4638 if (result < 0) {
4639 /* Don't clobber the OSError if the fork failed. */
4640 PyErr_SetString(PyExc_RuntimeError,
4641 "not holding the import lock");
4642 return NULL;
4643 }
4644 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004645}
4646#endif
4647
4648
Guido van Rossumad0ee831995-03-01 10:34:45 +00004649#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004650PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004651"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004652Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004653Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004654
Barry Warsaw53699e91996-12-10 23:23:01 +00004655static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004656posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004657{
Victor Stinner8c62be82010-05-06 00:08:46 +00004658 pid_t pid;
4659 int result = 0;
4660 _PyImport_AcquireLock();
4661 pid = fork();
4662 if (pid == 0) {
4663 /* child: this clobbers and resets the import lock. */
4664 PyOS_AfterFork();
4665 } else {
4666 /* parent: release the import lock. */
4667 result = _PyImport_ReleaseLock();
4668 }
4669 if (pid == -1)
4670 return posix_error();
4671 if (result < 0) {
4672 /* Don't clobber the OSError if the fork failed. */
4673 PyErr_SetString(PyExc_RuntimeError,
4674 "not holding the import lock");
4675 return NULL;
4676 }
4677 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004678}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004679#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004680
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004681#ifdef HAVE_SCHED_H
4682
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004683#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4684
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004685PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4686"sched_get_priority_max(policy)\n\n\
4687Get the maximum scheduling priority for *policy*.");
4688
4689static PyObject *
4690posix_sched_get_priority_max(PyObject *self, PyObject *args)
4691{
4692 int policy, max;
4693
4694 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4695 return NULL;
4696 max = sched_get_priority_max(policy);
4697 if (max < 0)
4698 return posix_error();
4699 return PyLong_FromLong(max);
4700}
4701
4702PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4703"sched_get_priority_min(policy)\n\n\
4704Get the minimum scheduling priority for *policy*.");
4705
4706static PyObject *
4707posix_sched_get_priority_min(PyObject *self, PyObject *args)
4708{
4709 int policy, min;
4710
4711 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4712 return NULL;
4713 min = sched_get_priority_min(policy);
4714 if (min < 0)
4715 return posix_error();
4716 return PyLong_FromLong(min);
4717}
4718
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004719#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4720
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004721#ifdef HAVE_SCHED_SETSCHEDULER
4722
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004723PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4724"sched_getscheduler(pid)\n\n\
4725Get the scheduling policy for the process with a PID of *pid*.\n\
4726Passing a PID of 0 returns the scheduling policy for the calling process.");
4727
4728static PyObject *
4729posix_sched_getscheduler(PyObject *self, PyObject *args)
4730{
4731 pid_t pid;
4732 int policy;
4733
4734 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4735 return NULL;
4736 policy = sched_getscheduler(pid);
4737 if (policy < 0)
4738 return posix_error();
4739 return PyLong_FromLong(policy);
4740}
4741
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004742#endif
4743
4744#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4745
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004746static PyObject *
4747sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4748{
4749 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004750 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004751
4752 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4753 return NULL;
4754 res = PyStructSequence_New(type);
4755 if (!res)
4756 return NULL;
4757 Py_INCREF(priority);
4758 PyStructSequence_SET_ITEM(res, 0, priority);
4759 return res;
4760}
4761
4762PyDoc_STRVAR(sched_param__doc__,
4763"sched_param(sched_priority): A scheduling parameter.\n\n\
4764Current has only one field: sched_priority");
4765
4766static PyStructSequence_Field sched_param_fields[] = {
4767 {"sched_priority", "the scheduling priority"},
4768 {0}
4769};
4770
4771static PyStructSequence_Desc sched_param_desc = {
4772 "sched_param", /* name */
4773 sched_param__doc__, /* doc */
4774 sched_param_fields,
4775 1
4776};
4777
4778static int
4779convert_sched_param(PyObject *param, struct sched_param *res)
4780{
4781 long priority;
4782
4783 if (Py_TYPE(param) != &SchedParamType) {
4784 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4785 return 0;
4786 }
4787 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4788 if (priority == -1 && PyErr_Occurred())
4789 return 0;
4790 if (priority > INT_MAX || priority < INT_MIN) {
4791 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4792 return 0;
4793 }
4794 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4795 return 1;
4796}
4797
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004798#endif
4799
4800#ifdef HAVE_SCHED_SETSCHEDULER
4801
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004802PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4803"sched_setscheduler(pid, policy, param)\n\n\
4804Set the scheduling policy, *policy*, for *pid*.\n\
4805If *pid* is 0, the calling process is changed.\n\
4806*param* is an instance of sched_param.");
4807
4808static PyObject *
4809posix_sched_setscheduler(PyObject *self, PyObject *args)
4810{
4811 pid_t pid;
4812 int policy;
4813 struct sched_param param;
4814
4815 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4816 &pid, &policy, &convert_sched_param, &param))
4817 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004818
4819 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004820 ** sched_setscheduler() returns 0 in Linux, but the previous
4821 ** scheduling policy under Solaris/Illumos, and others.
4822 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004823 */
4824 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004825 return posix_error();
4826 Py_RETURN_NONE;
4827}
4828
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004829#endif
4830
4831#ifdef HAVE_SCHED_SETPARAM
4832
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004833PyDoc_STRVAR(posix_sched_getparam__doc__,
4834"sched_getparam(pid) -> sched_param\n\n\
4835Returns scheduling parameters for the process with *pid* as an instance of the\n\
4836sched_param class. A PID of 0 means the calling process.");
4837
4838static PyObject *
4839posix_sched_getparam(PyObject *self, PyObject *args)
4840{
4841 pid_t pid;
4842 struct sched_param param;
4843 PyObject *res, *priority;
4844
4845 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4846 return NULL;
4847 if (sched_getparam(pid, &param))
4848 return posix_error();
4849 res = PyStructSequence_New(&SchedParamType);
4850 if (!res)
4851 return NULL;
4852 priority = PyLong_FromLong(param.sched_priority);
4853 if (!priority) {
4854 Py_DECREF(res);
4855 return NULL;
4856 }
4857 PyStructSequence_SET_ITEM(res, 0, priority);
4858 return res;
4859}
4860
4861PyDoc_STRVAR(posix_sched_setparam__doc__,
4862"sched_setparam(pid, param)\n\n\
4863Set scheduling parameters for a process with PID *pid*.\n\
4864A PID of 0 means the calling process.");
4865
4866static PyObject *
4867posix_sched_setparam(PyObject *self, PyObject *args)
4868{
4869 pid_t pid;
4870 struct sched_param param;
4871
4872 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4873 &pid, &convert_sched_param, &param))
4874 return NULL;
4875 if (sched_setparam(pid, &param))
4876 return posix_error();
4877 Py_RETURN_NONE;
4878}
4879
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004880#endif
4881
4882#ifdef HAVE_SCHED_RR_GET_INTERVAL
4883
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004884PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4885"sched_rr_get_interval(pid) -> float\n\n\
4886Return the round-robin quantum for the process with PID *pid* in seconds.");
4887
4888static PyObject *
4889posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4890{
4891 pid_t pid;
4892 struct timespec interval;
4893
4894 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4895 return NULL;
4896 if (sched_rr_get_interval(pid, &interval))
4897 return posix_error();
4898 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4899}
4900
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004901#endif
4902
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004903PyDoc_STRVAR(posix_sched_yield__doc__,
4904"sched_yield()\n\n\
4905Voluntarily relinquish the CPU.");
4906
4907static PyObject *
4908posix_sched_yield(PyObject *self, PyObject *noargs)
4909{
4910 if (sched_yield())
4911 return posix_error();
4912 Py_RETURN_NONE;
4913}
4914
Benjamin Peterson2740af82011-08-02 17:41:34 -05004915#ifdef HAVE_SCHED_SETAFFINITY
4916
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004917typedef struct {
4918 PyObject_HEAD;
4919 Py_ssize_t size;
4920 int ncpus;
4921 cpu_set_t *set;
4922} Py_cpu_set;
4923
4924static PyTypeObject cpu_set_type;
4925
4926static void
4927cpu_set_dealloc(Py_cpu_set *set)
4928{
4929 assert(set->set);
4930 CPU_FREE(set->set);
4931 Py_TYPE(set)->tp_free(set);
4932}
4933
4934static Py_cpu_set *
4935make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
4936{
4937 Py_cpu_set *set;
4938
4939 if (size < 0) {
4940 PyErr_SetString(PyExc_ValueError, "negative size");
4941 return NULL;
4942 }
4943 set = (Py_cpu_set *)type->tp_alloc(type, 0);
4944 if (!set)
4945 return NULL;
4946 set->ncpus = size;
4947 set->size = CPU_ALLOC_SIZE(size);
4948 set->set = CPU_ALLOC(size);
4949 if (!set->set) {
4950 type->tp_free(set);
4951 PyErr_NoMemory();
4952 return NULL;
4953 }
4954 CPU_ZERO_S(set->size, set->set);
4955 return set;
4956}
4957
4958static PyObject *
4959cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4960{
4961 int size;
4962
4963 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
4964 !PyArg_ParseTuple(args, "i:cpu_set", &size))
4965 return NULL;
4966 return (PyObject *)make_new_cpu_set(type, size);
4967}
4968
4969static PyObject *
4970cpu_set_repr(Py_cpu_set *set)
4971{
4972 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02004973}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004974
4975static Py_ssize_t
4976cpu_set_len(Py_cpu_set *set)
4977{
4978 return set->ncpus;
4979}
4980
4981static int
4982_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
4983{
4984 int cpu;
4985 if (!PyArg_ParseTuple(args, requester, &cpu))
4986 return -1;
4987 if (cpu < 0) {
4988 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
4989 return -1;
4990 }
4991 if (cpu >= set->ncpus) {
4992 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
4993 return -1;
4994 }
4995 return cpu;
4996}
4997
4998PyDoc_STRVAR(cpu_set_set_doc,
4999"cpu_set.set(i)\n\n\
5000Add CPU *i* to the set.");
5001
5002static PyObject *
5003cpu_set_set(Py_cpu_set *set, PyObject *args)
5004{
5005 int cpu = _get_cpu(set, "i|set", args);
5006 if (cpu == -1)
5007 return NULL;
5008 CPU_SET_S(cpu, set->size, set->set);
5009 Py_RETURN_NONE;
5010}
5011
5012PyDoc_STRVAR(cpu_set_count_doc,
5013"cpu_set.count() -> int\n\n\
5014Return the number of CPUs active in the set.");
5015
5016static PyObject *
5017cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5018{
5019 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5020}
5021
5022PyDoc_STRVAR(cpu_set_clear_doc,
5023"cpu_set.clear(i)\n\n\
5024Remove CPU *i* from the set.");
5025
5026static PyObject *
5027cpu_set_clear(Py_cpu_set *set, PyObject *args)
5028{
5029 int cpu = _get_cpu(set, "i|clear", args);
5030 if (cpu == -1)
5031 return NULL;
5032 CPU_CLR_S(cpu, set->size, set->set);
5033 Py_RETURN_NONE;
5034}
5035
5036PyDoc_STRVAR(cpu_set_isset_doc,
5037"cpu_set.isset(i) -> bool\n\n\
5038Test if CPU *i* is in the set.");
5039
5040static PyObject *
5041cpu_set_isset(Py_cpu_set *set, PyObject *args)
5042{
5043 int cpu = _get_cpu(set, "i|isset", args);
5044 if (cpu == -1)
5045 return NULL;
5046 if (CPU_ISSET_S(cpu, set->size, set->set))
5047 Py_RETURN_TRUE;
5048 Py_RETURN_FALSE;
5049}
5050
5051PyDoc_STRVAR(cpu_set_zero_doc,
5052"cpu_set.zero()\n\n\
5053Clear the cpu_set.");
5054
5055static PyObject *
5056cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5057{
5058 CPU_ZERO_S(set->size, set->set);
5059 Py_RETURN_NONE;
5060}
5061
5062static PyObject *
5063cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5064{
5065 int eq;
5066
Brian Curtindfc80e32011-08-10 20:28:54 -05005067 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5068 Py_RETURN_NOTIMPLEMENTED;
5069
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005070 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5071 if ((op == Py_EQ) ? eq : !eq)
5072 Py_RETURN_TRUE;
5073 else
5074 Py_RETURN_FALSE;
5075}
5076
5077#define CPU_SET_BINOP(name, op) \
5078 static PyObject * \
5079 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5080 if (res) { \
5081 Py_INCREF(res); \
5082 } \
5083 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005084 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005085 if (!res) \
5086 return NULL; \
5087 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005088 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005089 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005090 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005091 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005092 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005093 op(res->size, res->set, left->set, right->set); \
5094 return (PyObject *)res; \
5095 } \
5096 static PyObject * \
5097 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5098 return do_cpu_set_##name(left, right, NULL); \
5099 } \
5100 static PyObject * \
5101 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5102 return do_cpu_set_##name(left, right, left); \
5103 } \
5104
5105CPU_SET_BINOP(and, CPU_AND_S)
5106CPU_SET_BINOP(or, CPU_OR_S)
5107CPU_SET_BINOP(xor, CPU_XOR_S)
5108#undef CPU_SET_BINOP
5109
5110PyDoc_STRVAR(cpu_set_doc,
5111"cpu_set(size)\n\n\
5112Create an empty mask of CPUs.");
5113
5114static PyNumberMethods cpu_set_as_number = {
5115 0, /*nb_add*/
5116 0, /*nb_subtract*/
5117 0, /*nb_multiply*/
5118 0, /*nb_remainder*/
5119 0, /*nb_divmod*/
5120 0, /*nb_power*/
5121 0, /*nb_negative*/
5122 0, /*nb_positive*/
5123 0, /*nb_absolute*/
5124 0, /*nb_bool*/
5125 0, /*nb_invert*/
5126 0, /*nb_lshift*/
5127 0, /*nb_rshift*/
5128 (binaryfunc)cpu_set_and, /*nb_and*/
5129 (binaryfunc)cpu_set_xor, /*nb_xor*/
5130 (binaryfunc)cpu_set_or, /*nb_or*/
5131 0, /*nb_int*/
5132 0, /*nb_reserved*/
5133 0, /*nb_float*/
5134 0, /*nb_inplace_add*/
5135 0, /*nb_inplace_subtract*/
5136 0, /*nb_inplace_multiply*/
5137 0, /*nb_inplace_remainder*/
5138 0, /*nb_inplace_power*/
5139 0, /*nb_inplace_lshift*/
5140 0, /*nb_inplace_rshift*/
5141 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5142 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5143 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5144};
5145
5146static PySequenceMethods cpu_set_as_sequence = {
5147 (lenfunc)cpu_set_len, /* sq_length */
5148};
5149
5150static PyMethodDef cpu_set_methods[] = {
5151 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5152 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5153 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5154 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5155 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5156 {NULL, NULL} /* sentinel */
5157};
5158
5159static PyTypeObject cpu_set_type = {
5160 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5161 "posix.cpu_set", /* tp_name */
5162 sizeof(Py_cpu_set), /* tp_basicsize */
5163 0, /* tp_itemsize */
5164 /* methods */
5165 (destructor)cpu_set_dealloc, /* tp_dealloc */
5166 0, /* tp_print */
5167 0, /* tp_getattr */
5168 0, /* tp_setattr */
5169 0, /* tp_reserved */
5170 (reprfunc)cpu_set_repr, /* tp_repr */
5171 &cpu_set_as_number, /* tp_as_number */
5172 &cpu_set_as_sequence, /* tp_as_sequence */
5173 0, /* tp_as_mapping */
5174 PyObject_HashNotImplemented, /* tp_hash */
5175 0, /* tp_call */
5176 0, /* tp_str */
5177 PyObject_GenericGetAttr, /* tp_getattro */
5178 0, /* tp_setattro */
5179 0, /* tp_as_buffer */
5180 Py_TPFLAGS_DEFAULT, /* tp_flags */
5181 cpu_set_doc, /* tp_doc */
5182 0, /* tp_traverse */
5183 0, /* tp_clear */
5184 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5185 0, /* tp_weaklistoffset */
5186 0, /* tp_iter */
5187 0, /* tp_iternext */
5188 cpu_set_methods, /* tp_methods */
5189 0, /* tp_members */
5190 0, /* tp_getset */
5191 0, /* tp_base */
5192 0, /* tp_dict */
5193 0, /* tp_descr_get */
5194 0, /* tp_descr_set */
5195 0, /* tp_dictoffset */
5196 0, /* tp_init */
5197 PyType_GenericAlloc, /* tp_alloc */
5198 cpu_set_new, /* tp_new */
5199 PyObject_Del, /* tp_free */
5200};
5201
5202PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5203"sched_setaffinity(pid, cpu_set)\n\n\
5204Set the affinity of the process with PID *pid* to *cpu_set*.");
5205
5206static PyObject *
5207posix_sched_setaffinity(PyObject *self, PyObject *args)
5208{
5209 pid_t pid;
5210 Py_cpu_set *cpu_set;
5211
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005212 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005213 &pid, &cpu_set_type, &cpu_set))
5214 return NULL;
5215 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5216 return posix_error();
5217 Py_RETURN_NONE;
5218}
5219
5220PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5221"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5222Return the affinity of the process with PID *pid*.\n\
5223The returned cpu_set will be of size *ncpus*.");
5224
5225static PyObject *
5226posix_sched_getaffinity(PyObject *self, PyObject *args)
5227{
5228 pid_t pid;
5229 int ncpus;
5230 Py_cpu_set *res;
5231
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005232 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005233 &pid, &ncpus))
5234 return NULL;
5235 res = make_new_cpu_set(&cpu_set_type, ncpus);
5236 if (!res)
5237 return NULL;
5238 if (sched_getaffinity(pid, res->size, res->set)) {
5239 Py_DECREF(res);
5240 return posix_error();
5241 }
5242 return (PyObject *)res;
5243}
5244
Benjamin Peterson2740af82011-08-02 17:41:34 -05005245#endif /* HAVE_SCHED_SETAFFINITY */
5246
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005247#endif /* HAVE_SCHED_H */
5248
Neal Norwitzb59798b2003-03-21 01:43:31 +00005249/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005250/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5251#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005252#define DEV_PTY_FILE "/dev/ptc"
5253#define HAVE_DEV_PTMX
5254#else
5255#define DEV_PTY_FILE "/dev/ptmx"
5256#endif
5257
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005258#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005259#ifdef HAVE_PTY_H
5260#include <pty.h>
5261#else
5262#ifdef HAVE_LIBUTIL_H
5263#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005264#else
5265#ifdef HAVE_UTIL_H
5266#include <util.h>
5267#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005268#endif /* HAVE_LIBUTIL_H */
5269#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005270#ifdef HAVE_STROPTS_H
5271#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005272#endif
5273#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005274
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005275#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005276PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005277"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005278Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005279
5280static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005281posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005282{
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005284#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005285 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005286#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005287#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005288 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005289#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005290 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005291#endif
5292#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005293
Thomas Wouters70c21a12000-07-14 14:28:33 +00005294#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5296 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005297#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5299 if (slave_name == NULL)
5300 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005301
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 slave_fd = open(slave_name, O_RDWR);
5303 if (slave_fd < 0)
5304 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005305#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5307 if (master_fd < 0)
5308 return posix_error();
5309 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5310 /* change permission of slave */
5311 if (grantpt(master_fd) < 0) {
5312 PyOS_setsig(SIGCHLD, sig_saved);
5313 return posix_error();
5314 }
5315 /* unlock slave */
5316 if (unlockpt(master_fd) < 0) {
5317 PyOS_setsig(SIGCHLD, sig_saved);
5318 return posix_error();
5319 }
5320 PyOS_setsig(SIGCHLD, sig_saved);
5321 slave_name = ptsname(master_fd); /* get name of slave */
5322 if (slave_name == NULL)
5323 return posix_error();
5324 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5325 if (slave_fd < 0)
5326 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005327#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005328 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5329 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005330#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005331 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005332#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005333#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005334#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005335
Victor Stinner8c62be82010-05-06 00:08:46 +00005336 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005337
Fred Drake8cef4cf2000-06-28 16:40:38 +00005338}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005339#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005340
5341#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005342PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005343"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005344Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5345Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005346To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005347
5348static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005349posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005350{
Victor Stinner8c62be82010-05-06 00:08:46 +00005351 int master_fd = -1, result = 0;
5352 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005353
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 _PyImport_AcquireLock();
5355 pid = forkpty(&master_fd, NULL, NULL, NULL);
5356 if (pid == 0) {
5357 /* child: this clobbers and resets the import lock. */
5358 PyOS_AfterFork();
5359 } else {
5360 /* parent: release the import lock. */
5361 result = _PyImport_ReleaseLock();
5362 }
5363 if (pid == -1)
5364 return posix_error();
5365 if (result < 0) {
5366 /* Don't clobber the OSError if the fork failed. */
5367 PyErr_SetString(PyExc_RuntimeError,
5368 "not holding the import lock");
5369 return NULL;
5370 }
5371 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005372}
5373#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005374
Ross Lagerwall7807c352011-03-17 20:20:30 +02005375
Guido van Rossumad0ee831995-03-01 10:34:45 +00005376#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005377PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005378"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005379Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005380
Barry Warsaw53699e91996-12-10 23:23:01 +00005381static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005382posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005383{
Victor Stinner8c62be82010-05-06 00:08:46 +00005384 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005385}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005386#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005387
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005388
Guido van Rossumad0ee831995-03-01 10:34:45 +00005389#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005390PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005391"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005392Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005393
Barry Warsaw53699e91996-12-10 23:23:01 +00005394static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005395posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005396{
Victor Stinner8c62be82010-05-06 00:08:46 +00005397 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005398}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005399#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005400
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005401
Guido van Rossumad0ee831995-03-01 10:34:45 +00005402#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005403PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005404"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005405Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005406
Barry Warsaw53699e91996-12-10 23:23:01 +00005407static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005408posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005409{
Victor Stinner8c62be82010-05-06 00:08:46 +00005410 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005411}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005412#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005414
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005415PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005416"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005417Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005418
Barry Warsaw53699e91996-12-10 23:23:01 +00005419static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005420posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005421{
Victor Stinner8c62be82010-05-06 00:08:46 +00005422 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005423}
5424
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005425#ifdef HAVE_GETGROUPLIST
5426PyDoc_STRVAR(posix_getgrouplist__doc__,
5427"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5428Returns a list of groups to which a user belongs.\n\n\
5429 user: username to lookup\n\
5430 group: base group id of the user");
5431
5432static PyObject *
5433posix_getgrouplist(PyObject *self, PyObject *args)
5434{
5435#ifdef NGROUPS_MAX
5436#define MAX_GROUPS NGROUPS_MAX
5437#else
5438 /* defined to be 16 on Solaris7, so this should be a small number */
5439#define MAX_GROUPS 64
5440#endif
5441
5442 const char *user;
5443 int i, ngroups;
5444 PyObject *list;
5445#ifdef __APPLE__
5446 int *groups, basegid;
5447#else
5448 gid_t *groups, basegid;
5449#endif
5450 ngroups = MAX_GROUPS;
5451
5452 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5453 return NULL;
5454
5455#ifdef __APPLE__
5456 groups = PyMem_Malloc(ngroups * sizeof(int));
5457#else
5458 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5459#endif
5460 if (groups == NULL)
5461 return PyErr_NoMemory();
5462
5463 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5464 PyMem_Del(groups);
5465 return posix_error();
5466 }
5467
5468 list = PyList_New(ngroups);
5469 if (list == NULL) {
5470 PyMem_Del(groups);
5471 return NULL;
5472 }
5473
5474 for (i = 0; i < ngroups; i++) {
5475 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5476 if (o == NULL) {
5477 Py_DECREF(list);
5478 PyMem_Del(groups);
5479 return NULL;
5480 }
5481 PyList_SET_ITEM(list, i, o);
5482 }
5483
5484 PyMem_Del(groups);
5485
5486 return list;
5487}
5488#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005489
Fred Drakec9680921999-12-13 16:37:25 +00005490#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005491PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005492"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005493Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005494
5495static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005496posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005497{
5498 PyObject *result = NULL;
5499
Fred Drakec9680921999-12-13 16:37:25 +00005500#ifdef NGROUPS_MAX
5501#define MAX_GROUPS NGROUPS_MAX
5502#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005503 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005504#define MAX_GROUPS 64
5505#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005506 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005507
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005508 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005509 * This is a helper variable to store the intermediate result when
5510 * that happens.
5511 *
5512 * To keep the code readable the OSX behaviour is unconditional,
5513 * according to the POSIX spec this should be safe on all unix-y
5514 * systems.
5515 */
5516 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005517 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005518
Victor Stinner8c62be82010-05-06 00:08:46 +00005519 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005520 if (n < 0) {
5521 if (errno == EINVAL) {
5522 n = getgroups(0, NULL);
5523 if (n == -1) {
5524 return posix_error();
5525 }
5526 if (n == 0) {
5527 /* Avoid malloc(0) */
5528 alt_grouplist = grouplist;
5529 } else {
5530 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5531 if (alt_grouplist == NULL) {
5532 errno = EINVAL;
5533 return posix_error();
5534 }
5535 n = getgroups(n, alt_grouplist);
5536 if (n == -1) {
5537 PyMem_Free(alt_grouplist);
5538 return posix_error();
5539 }
5540 }
5541 } else {
5542 return posix_error();
5543 }
5544 }
5545 result = PyList_New(n);
5546 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005547 int i;
5548 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005549 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005550 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005551 Py_DECREF(result);
5552 result = NULL;
5553 break;
Fred Drakec9680921999-12-13 16:37:25 +00005554 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005556 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005557 }
5558
5559 if (alt_grouplist != grouplist) {
5560 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005561 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005562
Fred Drakec9680921999-12-13 16:37:25 +00005563 return result;
5564}
5565#endif
5566
Antoine Pitroub7572f02009-12-02 20:46:48 +00005567#ifdef HAVE_INITGROUPS
5568PyDoc_STRVAR(posix_initgroups__doc__,
5569"initgroups(username, gid) -> None\n\n\
5570Call the system initgroups() to initialize the group access list with all of\n\
5571the groups of which the specified username is a member, plus the specified\n\
5572group id.");
5573
5574static PyObject *
5575posix_initgroups(PyObject *self, PyObject *args)
5576{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005577 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005578 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005579 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005580 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005581
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005582 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5583 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005584 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005585 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005586
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005587 res = initgroups(username, (gid_t) gid);
5588 Py_DECREF(oname);
5589 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005590 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005591
Victor Stinner8c62be82010-05-06 00:08:46 +00005592 Py_INCREF(Py_None);
5593 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005594}
5595#endif
5596
Martin v. Löwis606edc12002-06-13 21:09:11 +00005597#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005598PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005599"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005600Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005601
5602static PyObject *
5603posix_getpgid(PyObject *self, PyObject *args)
5604{
Victor Stinner8c62be82010-05-06 00:08:46 +00005605 pid_t pid, pgid;
5606 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5607 return NULL;
5608 pgid = getpgid(pid);
5609 if (pgid < 0)
5610 return posix_error();
5611 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005612}
5613#endif /* HAVE_GETPGID */
5614
5615
Guido van Rossumb6775db1994-08-01 11:34:53 +00005616#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005617PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005618"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005619Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005620
Barry Warsaw53699e91996-12-10 23:23:01 +00005621static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005622posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005623{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005624#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005625 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005626#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005627 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005628#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005629}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005630#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005631
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005632
Guido van Rossumb6775db1994-08-01 11:34:53 +00005633#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005634PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005635"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005636Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005637
Barry Warsaw53699e91996-12-10 23:23:01 +00005638static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005639posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005640{
Guido van Rossum64933891994-10-20 21:56:42 +00005641#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005642 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005643#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005644 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005645#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005646 return posix_error();
5647 Py_INCREF(Py_None);
5648 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005649}
5650
Guido van Rossumb6775db1994-08-01 11:34:53 +00005651#endif /* HAVE_SETPGRP */
5652
Guido van Rossumad0ee831995-03-01 10:34:45 +00005653#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005654
5655#ifdef MS_WINDOWS
5656#include <tlhelp32.h>
5657
5658static PyObject*
5659win32_getppid()
5660{
5661 HANDLE snapshot;
5662 pid_t mypid;
5663 PyObject* result = NULL;
5664 BOOL have_record;
5665 PROCESSENTRY32 pe;
5666
5667 mypid = getpid(); /* This function never fails */
5668
5669 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5670 if (snapshot == INVALID_HANDLE_VALUE)
5671 return PyErr_SetFromWindowsErr(GetLastError());
5672
5673 pe.dwSize = sizeof(pe);
5674 have_record = Process32First(snapshot, &pe);
5675 while (have_record) {
5676 if (mypid == (pid_t)pe.th32ProcessID) {
5677 /* We could cache the ulong value in a static variable. */
5678 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5679 break;
5680 }
5681
5682 have_record = Process32Next(snapshot, &pe);
5683 }
5684
5685 /* If our loop exits and our pid was not found (result will be NULL)
5686 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5687 * error anyway, so let's raise it. */
5688 if (!result)
5689 result = PyErr_SetFromWindowsErr(GetLastError());
5690
5691 CloseHandle(snapshot);
5692
5693 return result;
5694}
5695#endif /*MS_WINDOWS*/
5696
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005697PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005698"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005699Return the parent's process id. If the parent process has already exited,\n\
5700Windows machines will still return its id; others systems will return the id\n\
5701of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005702
Barry Warsaw53699e91996-12-10 23:23:01 +00005703static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005704posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005705{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005706#ifdef MS_WINDOWS
5707 return win32_getppid();
5708#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005709 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005710#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005711}
5712#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005713
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005714
Fred Drake12c6e2d1999-12-14 21:25:03 +00005715#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005716PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005717"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005719
5720static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005721posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005722{
Victor Stinner8c62be82010-05-06 00:08:46 +00005723 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005724#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005725 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005726 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005727
5728 if (GetUserNameW(user_name, &num_chars)) {
5729 /* num_chars is the number of unicode chars plus null terminator */
5730 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005731 }
5732 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005733 result = PyErr_SetFromWindowsErr(GetLastError());
5734#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 char *name;
5736 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005737
Victor Stinner8c62be82010-05-06 00:08:46 +00005738 errno = 0;
5739 name = getlogin();
5740 if (name == NULL) {
5741 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005742 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005743 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005744 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 }
5746 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005747 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005748 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005749#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005750 return result;
5751}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005752#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005753
Guido van Rossumad0ee831995-03-01 10:34:45 +00005754#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005755PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005756"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005757Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005758
Barry Warsaw53699e91996-12-10 23:23:01 +00005759static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005760posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005761{
Victor Stinner8c62be82010-05-06 00:08:46 +00005762 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005763}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005764#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005765
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005766
Guido van Rossumad0ee831995-03-01 10:34:45 +00005767#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005768PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005769"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005770Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005771
Barry Warsaw53699e91996-12-10 23:23:01 +00005772static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005773posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005774{
Victor Stinner8c62be82010-05-06 00:08:46 +00005775 pid_t pid;
5776 int sig;
5777 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5778 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005779#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005780 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5781 APIRET rc;
5782 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005783 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005784
5785 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5786 APIRET rc;
5787 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005788 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005789
5790 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005791 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005792#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005793 if (kill(pid, sig) == -1)
5794 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005795#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005796 Py_INCREF(Py_None);
5797 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005798}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005799#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005800
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005801#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005802PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005803"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005804Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005805
5806static PyObject *
5807posix_killpg(PyObject *self, PyObject *args)
5808{
Victor Stinner8c62be82010-05-06 00:08:46 +00005809 int sig;
5810 pid_t pgid;
5811 /* XXX some man pages make the `pgid` parameter an int, others
5812 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5813 take the same type. Moreover, pid_t is always at least as wide as
5814 int (else compilation of this module fails), which is safe. */
5815 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5816 return NULL;
5817 if (killpg(pgid, sig) == -1)
5818 return posix_error();
5819 Py_INCREF(Py_None);
5820 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005821}
5822#endif
5823
Brian Curtineb24d742010-04-12 17:16:38 +00005824#ifdef MS_WINDOWS
5825PyDoc_STRVAR(win32_kill__doc__,
5826"kill(pid, sig)\n\n\
5827Kill a process with a signal.");
5828
5829static PyObject *
5830win32_kill(PyObject *self, PyObject *args)
5831{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005832 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 DWORD pid, sig, err;
5834 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005835
Victor Stinner8c62be82010-05-06 00:08:46 +00005836 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5837 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005838
Victor Stinner8c62be82010-05-06 00:08:46 +00005839 /* Console processes which share a common console can be sent CTRL+C or
5840 CTRL+BREAK events, provided they handle said events. */
5841 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5842 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5843 err = GetLastError();
5844 PyErr_SetFromWindowsErr(err);
5845 }
5846 else
5847 Py_RETURN_NONE;
5848 }
Brian Curtineb24d742010-04-12 17:16:38 +00005849
Victor Stinner8c62be82010-05-06 00:08:46 +00005850 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5851 attempt to open and terminate the process. */
5852 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5853 if (handle == NULL) {
5854 err = GetLastError();
5855 return PyErr_SetFromWindowsErr(err);
5856 }
Brian Curtineb24d742010-04-12 17:16:38 +00005857
Victor Stinner8c62be82010-05-06 00:08:46 +00005858 if (TerminateProcess(handle, sig) == 0) {
5859 err = GetLastError();
5860 result = PyErr_SetFromWindowsErr(err);
5861 } else {
5862 Py_INCREF(Py_None);
5863 result = Py_None;
5864 }
Brian Curtineb24d742010-04-12 17:16:38 +00005865
Victor Stinner8c62be82010-05-06 00:08:46 +00005866 CloseHandle(handle);
5867 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005868}
5869#endif /* MS_WINDOWS */
5870
Guido van Rossumc0125471996-06-28 18:55:32 +00005871#ifdef HAVE_PLOCK
5872
5873#ifdef HAVE_SYS_LOCK_H
5874#include <sys/lock.h>
5875#endif
5876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005877PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005878"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005879Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005880
Barry Warsaw53699e91996-12-10 23:23:01 +00005881static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005882posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005883{
Victor Stinner8c62be82010-05-06 00:08:46 +00005884 int op;
5885 if (!PyArg_ParseTuple(args, "i:plock", &op))
5886 return NULL;
5887 if (plock(op) == -1)
5888 return posix_error();
5889 Py_INCREF(Py_None);
5890 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005891}
5892#endif
5893
Guido van Rossumb6775db1994-08-01 11:34:53 +00005894#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005895PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005896"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005897Set the current process's user id.");
5898
Barry Warsaw53699e91996-12-10 23:23:01 +00005899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005900posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005901{
Victor Stinner8c62be82010-05-06 00:08:46 +00005902 long uid_arg;
5903 uid_t uid;
5904 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5905 return NULL;
5906 uid = uid_arg;
5907 if (uid != uid_arg) {
5908 PyErr_SetString(PyExc_OverflowError, "user id too big");
5909 return NULL;
5910 }
5911 if (setuid(uid) < 0)
5912 return posix_error();
5913 Py_INCREF(Py_None);
5914 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005915}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005916#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005917
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005918
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005919#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005920PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005921"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005922Set the current process's effective user id.");
5923
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005924static PyObject *
5925posix_seteuid (PyObject *self, PyObject *args)
5926{
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 long euid_arg;
5928 uid_t euid;
5929 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5930 return NULL;
5931 euid = euid_arg;
5932 if (euid != euid_arg) {
5933 PyErr_SetString(PyExc_OverflowError, "user id too big");
5934 return NULL;
5935 }
5936 if (seteuid(euid) < 0) {
5937 return posix_error();
5938 } else {
5939 Py_INCREF(Py_None);
5940 return Py_None;
5941 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005942}
5943#endif /* HAVE_SETEUID */
5944
5945#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005946PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005947"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005948Set the current process's effective group id.");
5949
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005950static PyObject *
5951posix_setegid (PyObject *self, PyObject *args)
5952{
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 long egid_arg;
5954 gid_t egid;
5955 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5956 return NULL;
5957 egid = egid_arg;
5958 if (egid != egid_arg) {
5959 PyErr_SetString(PyExc_OverflowError, "group id too big");
5960 return NULL;
5961 }
5962 if (setegid(egid) < 0) {
5963 return posix_error();
5964 } else {
5965 Py_INCREF(Py_None);
5966 return Py_None;
5967 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005968}
5969#endif /* HAVE_SETEGID */
5970
5971#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005972PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005973"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005974Set the current process's real and effective user ids.");
5975
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005976static PyObject *
5977posix_setreuid (PyObject *self, PyObject *args)
5978{
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 long ruid_arg, euid_arg;
5980 uid_t ruid, euid;
5981 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5982 return NULL;
5983 if (ruid_arg == -1)
5984 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5985 else
5986 ruid = ruid_arg; /* otherwise, assign from our long */
5987 if (euid_arg == -1)
5988 euid = (uid_t)-1;
5989 else
5990 euid = euid_arg;
5991 if ((euid_arg != -1 && euid != euid_arg) ||
5992 (ruid_arg != -1 && ruid != ruid_arg)) {
5993 PyErr_SetString(PyExc_OverflowError, "user id too big");
5994 return NULL;
5995 }
5996 if (setreuid(ruid, euid) < 0) {
5997 return posix_error();
5998 } else {
5999 Py_INCREF(Py_None);
6000 return Py_None;
6001 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006002}
6003#endif /* HAVE_SETREUID */
6004
6005#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006006PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006007"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006008Set the current process's real and effective group ids.");
6009
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006010static PyObject *
6011posix_setregid (PyObject *self, PyObject *args)
6012{
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 long rgid_arg, egid_arg;
6014 gid_t rgid, egid;
6015 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6016 return NULL;
6017 if (rgid_arg == -1)
6018 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6019 else
6020 rgid = rgid_arg; /* otherwise, assign from our long */
6021 if (egid_arg == -1)
6022 egid = (gid_t)-1;
6023 else
6024 egid = egid_arg;
6025 if ((egid_arg != -1 && egid != egid_arg) ||
6026 (rgid_arg != -1 && rgid != rgid_arg)) {
6027 PyErr_SetString(PyExc_OverflowError, "group id too big");
6028 return NULL;
6029 }
6030 if (setregid(rgid, egid) < 0) {
6031 return posix_error();
6032 } else {
6033 Py_INCREF(Py_None);
6034 return Py_None;
6035 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006036}
6037#endif /* HAVE_SETREGID */
6038
Guido van Rossumb6775db1994-08-01 11:34:53 +00006039#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006040PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006041"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006042Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006043
Barry Warsaw53699e91996-12-10 23:23:01 +00006044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006045posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006046{
Victor Stinner8c62be82010-05-06 00:08:46 +00006047 long gid_arg;
6048 gid_t gid;
6049 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6050 return NULL;
6051 gid = gid_arg;
6052 if (gid != gid_arg) {
6053 PyErr_SetString(PyExc_OverflowError, "group id too big");
6054 return NULL;
6055 }
6056 if (setgid(gid) < 0)
6057 return posix_error();
6058 Py_INCREF(Py_None);
6059 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006060}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006061#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006062
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006063#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006064PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006065"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006066Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006067
6068static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006069posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006070{
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 int i, len;
6072 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006073
Victor Stinner8c62be82010-05-06 00:08:46 +00006074 if (!PySequence_Check(groups)) {
6075 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6076 return NULL;
6077 }
6078 len = PySequence_Size(groups);
6079 if (len > MAX_GROUPS) {
6080 PyErr_SetString(PyExc_ValueError, "too many groups");
6081 return NULL;
6082 }
6083 for(i = 0; i < len; i++) {
6084 PyObject *elem;
6085 elem = PySequence_GetItem(groups, i);
6086 if (!elem)
6087 return NULL;
6088 if (!PyLong_Check(elem)) {
6089 PyErr_SetString(PyExc_TypeError,
6090 "groups must be integers");
6091 Py_DECREF(elem);
6092 return NULL;
6093 } else {
6094 unsigned long x = PyLong_AsUnsignedLong(elem);
6095 if (PyErr_Occurred()) {
6096 PyErr_SetString(PyExc_TypeError,
6097 "group id too big");
6098 Py_DECREF(elem);
6099 return NULL;
6100 }
6101 grouplist[i] = x;
6102 /* read back the value to see if it fitted in gid_t */
6103 if (grouplist[i] != x) {
6104 PyErr_SetString(PyExc_TypeError,
6105 "group id too big");
6106 Py_DECREF(elem);
6107 return NULL;
6108 }
6109 }
6110 Py_DECREF(elem);
6111 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006112
Victor Stinner8c62be82010-05-06 00:08:46 +00006113 if (setgroups(len, grouplist) < 0)
6114 return posix_error();
6115 Py_INCREF(Py_None);
6116 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006117}
6118#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006119
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006120#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6121static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00006122wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006123{
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 PyObject *result;
6125 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006126 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006127
Victor Stinner8c62be82010-05-06 00:08:46 +00006128 if (pid == -1)
6129 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006130
Victor Stinner8c62be82010-05-06 00:08:46 +00006131 if (struct_rusage == NULL) {
6132 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6133 if (m == NULL)
6134 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006135 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006136 Py_DECREF(m);
6137 if (struct_rusage == NULL)
6138 return NULL;
6139 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006140
Victor Stinner8c62be82010-05-06 00:08:46 +00006141 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6142 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6143 if (!result)
6144 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006145
6146#ifndef doubletime
6147#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6148#endif
6149
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 PyStructSequence_SET_ITEM(result, 0,
6151 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6152 PyStructSequence_SET_ITEM(result, 1,
6153 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006154#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006155 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6156 SET_INT(result, 2, ru->ru_maxrss);
6157 SET_INT(result, 3, ru->ru_ixrss);
6158 SET_INT(result, 4, ru->ru_idrss);
6159 SET_INT(result, 5, ru->ru_isrss);
6160 SET_INT(result, 6, ru->ru_minflt);
6161 SET_INT(result, 7, ru->ru_majflt);
6162 SET_INT(result, 8, ru->ru_nswap);
6163 SET_INT(result, 9, ru->ru_inblock);
6164 SET_INT(result, 10, ru->ru_oublock);
6165 SET_INT(result, 11, ru->ru_msgsnd);
6166 SET_INT(result, 12, ru->ru_msgrcv);
6167 SET_INT(result, 13, ru->ru_nsignals);
6168 SET_INT(result, 14, ru->ru_nvcsw);
6169 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006170#undef SET_INT
6171
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 if (PyErr_Occurred()) {
6173 Py_DECREF(result);
6174 return NULL;
6175 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006176
Victor Stinner8c62be82010-05-06 00:08:46 +00006177 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006178}
6179#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6180
6181#ifdef HAVE_WAIT3
6182PyDoc_STRVAR(posix_wait3__doc__,
6183"wait3(options) -> (pid, status, rusage)\n\n\
6184Wait for completion of a child process.");
6185
6186static PyObject *
6187posix_wait3(PyObject *self, PyObject *args)
6188{
Victor Stinner8c62be82010-05-06 00:08:46 +00006189 pid_t pid;
6190 int options;
6191 struct rusage ru;
6192 WAIT_TYPE status;
6193 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006194
Victor Stinner8c62be82010-05-06 00:08:46 +00006195 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6196 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006197
Victor Stinner8c62be82010-05-06 00:08:46 +00006198 Py_BEGIN_ALLOW_THREADS
6199 pid = wait3(&status, options, &ru);
6200 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006201
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006203}
6204#endif /* HAVE_WAIT3 */
6205
6206#ifdef HAVE_WAIT4
6207PyDoc_STRVAR(posix_wait4__doc__,
6208"wait4(pid, options) -> (pid, status, rusage)\n\n\
6209Wait for completion of a given child process.");
6210
6211static PyObject *
6212posix_wait4(PyObject *self, PyObject *args)
6213{
Victor Stinner8c62be82010-05-06 00:08:46 +00006214 pid_t pid;
6215 int options;
6216 struct rusage ru;
6217 WAIT_TYPE status;
6218 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006219
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
6221 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006222
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 Py_BEGIN_ALLOW_THREADS
6224 pid = wait4(pid, &status, options, &ru);
6225 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006226
Victor Stinner8c62be82010-05-06 00:08:46 +00006227 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006228}
6229#endif /* HAVE_WAIT4 */
6230
Ross Lagerwall7807c352011-03-17 20:20:30 +02006231#if defined(HAVE_WAITID) && !defined(__APPLE__)
6232PyDoc_STRVAR(posix_waitid__doc__,
6233"waitid(idtype, id, options) -> waitid_result\n\n\
6234Wait for the completion of one or more child processes.\n\n\
6235idtype can be P_PID, P_PGID or P_ALL.\n\
6236id specifies the pid to wait on.\n\
6237options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6238or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6239Returns either waitid_result or None if WNOHANG is specified and there are\n\
6240no children in a waitable state.");
6241
6242static PyObject *
6243posix_waitid(PyObject *self, PyObject *args)
6244{
6245 PyObject *result;
6246 idtype_t idtype;
6247 id_t id;
6248 int options, res;
6249 siginfo_t si;
6250 si.si_pid = 0;
6251 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6252 return NULL;
6253 Py_BEGIN_ALLOW_THREADS
6254 res = waitid(idtype, id, &si, options);
6255 Py_END_ALLOW_THREADS
6256 if (res == -1)
6257 return posix_error();
6258
6259 if (si.si_pid == 0)
6260 Py_RETURN_NONE;
6261
6262 result = PyStructSequence_New(&WaitidResultType);
6263 if (!result)
6264 return NULL;
6265
6266 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6267 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6268 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6269 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6270 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6271 if (PyErr_Occurred()) {
6272 Py_DECREF(result);
6273 return NULL;
6274 }
6275
6276 return result;
6277}
6278#endif
6279
Guido van Rossumb6775db1994-08-01 11:34:53 +00006280#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006281PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006282"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006283Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006284
Barry Warsaw53699e91996-12-10 23:23:01 +00006285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006286posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006287{
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 pid_t pid;
6289 int options;
6290 WAIT_TYPE status;
6291 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006292
Victor Stinner8c62be82010-05-06 00:08:46 +00006293 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6294 return NULL;
6295 Py_BEGIN_ALLOW_THREADS
6296 pid = waitpid(pid, &status, options);
6297 Py_END_ALLOW_THREADS
6298 if (pid == -1)
6299 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006300
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006302}
6303
Tim Petersab034fa2002-02-01 11:27:43 +00006304#elif defined(HAVE_CWAIT)
6305
6306/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006307PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006308"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006309"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006310
6311static PyObject *
6312posix_waitpid(PyObject *self, PyObject *args)
6313{
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 Py_intptr_t pid;
6315 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006316
Victor Stinner8c62be82010-05-06 00:08:46 +00006317 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6318 return NULL;
6319 Py_BEGIN_ALLOW_THREADS
6320 pid = _cwait(&status, pid, options);
6321 Py_END_ALLOW_THREADS
6322 if (pid == -1)
6323 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006324
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 /* shift the status left a byte so this is more like the POSIX waitpid */
6326 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006327}
6328#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006329
Guido van Rossumad0ee831995-03-01 10:34:45 +00006330#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006331PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006332"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006333Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006334
Barry Warsaw53699e91996-12-10 23:23:01 +00006335static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006336posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006337{
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 pid_t pid;
6339 WAIT_TYPE status;
6340 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006341
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 Py_BEGIN_ALLOW_THREADS
6343 pid = wait(&status);
6344 Py_END_ALLOW_THREADS
6345 if (pid == -1)
6346 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006347
Victor Stinner8c62be82010-05-06 00:08:46 +00006348 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006349}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006350#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006352
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006353PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006354"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006355Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006356
Barry Warsaw53699e91996-12-10 23:23:01 +00006357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006358posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006359{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006360#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00006361 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006362#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006363#ifdef MS_WINDOWS
Brian Curtind25aef52011-06-13 15:16:04 -05006364 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006365 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006366#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006368#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006369#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006370}
6371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006372
Guido van Rossumb6775db1994-08-01 11:34:53 +00006373#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006374PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006375"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006376Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006377
Barry Warsaw53699e91996-12-10 23:23:01 +00006378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006379posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006380{
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 PyObject* v;
6382 char buf[MAXPATHLEN];
6383 PyObject *opath;
6384 char *path;
6385 int n;
6386 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006387
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 if (!PyArg_ParseTuple(args, "O&:readlink",
6389 PyUnicode_FSConverter, &opath))
6390 return NULL;
6391 path = PyBytes_AsString(opath);
6392 v = PySequence_GetItem(args, 0);
6393 if (v == NULL) {
6394 Py_DECREF(opath);
6395 return NULL;
6396 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006397
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 if (PyUnicode_Check(v)) {
6399 arg_is_unicode = 1;
6400 }
6401 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006402
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 Py_BEGIN_ALLOW_THREADS
6404 n = readlink(path, buf, (int) sizeof buf);
6405 Py_END_ALLOW_THREADS
6406 if (n < 0)
6407 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006408
Victor Stinner8c62be82010-05-06 00:08:46 +00006409 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006410 if (arg_is_unicode)
6411 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6412 else
6413 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006414}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006415#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006417
Brian Curtin52173d42010-12-02 18:29:18 +00006418#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006419PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006420"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006421Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006422
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006424posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006425{
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006427}
6428#endif /* HAVE_SYMLINK */
6429
Brian Curtind40e6f72010-07-08 21:39:08 +00006430#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6431
6432PyDoc_STRVAR(win_readlink__doc__,
6433"readlink(path) -> path\n\n\
6434Return a string representing the path to which the symbolic link points.");
6435
Brian Curtind40e6f72010-07-08 21:39:08 +00006436/* Windows readlink implementation */
6437static PyObject *
6438win_readlink(PyObject *self, PyObject *args)
6439{
6440 wchar_t *path;
6441 DWORD n_bytes_returned;
6442 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006443 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00006444 HANDLE reparse_point_handle;
6445
6446 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6447 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6448 wchar_t *print_name;
6449
6450 if (!PyArg_ParseTuple(args,
Victor Stinnereb5657a2011-09-30 01:44:27 +02006451 "U:readlink",
6452 &po))
6453 return NULL;
6454 path = PyUnicode_AsUnicode(po);
6455 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006456 return NULL;
6457
6458 /* First get a handle to the reparse point */
6459 Py_BEGIN_ALLOW_THREADS
6460 reparse_point_handle = CreateFileW(
6461 path,
6462 0,
6463 0,
6464 0,
6465 OPEN_EXISTING,
6466 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6467 0);
6468 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006469
Brian Curtind40e6f72010-07-08 21:39:08 +00006470 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006471 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006472
Brian Curtind40e6f72010-07-08 21:39:08 +00006473 Py_BEGIN_ALLOW_THREADS
6474 /* New call DeviceIoControl to read the reparse point */
6475 io_result = DeviceIoControl(
6476 reparse_point_handle,
6477 FSCTL_GET_REPARSE_POINT,
6478 0, 0, /* in buffer */
6479 target_buffer, sizeof(target_buffer),
6480 &n_bytes_returned,
6481 0 /* we're not using OVERLAPPED_IO */
6482 );
6483 CloseHandle(reparse_point_handle);
6484 Py_END_ALLOW_THREADS
6485
6486 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006487 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006488
6489 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6490 {
6491 PyErr_SetString(PyExc_ValueError,
6492 "not a symbolic link");
6493 return NULL;
6494 }
Brian Curtin74e45612010-07-09 15:58:59 +00006495 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6496 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6497
6498 result = PyUnicode_FromWideChar(print_name,
6499 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006500 return result;
6501}
6502
6503#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6504
Brian Curtin52173d42010-12-02 18:29:18 +00006505#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006506
6507/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6508static int has_CreateSymbolicLinkW = 0;
6509static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6510static int
6511check_CreateSymbolicLinkW()
6512{
6513 HINSTANCE hKernel32;
6514 /* only recheck */
6515 if (has_CreateSymbolicLinkW)
6516 return has_CreateSymbolicLinkW;
Martin v. Löwis50590f12012-01-14 17:54:09 +01006517 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006518 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6519 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006520 if (Py_CreateSymbolicLinkW)
6521 has_CreateSymbolicLinkW = 1;
6522 return has_CreateSymbolicLinkW;
6523}
6524
6525PyDoc_STRVAR(win_symlink__doc__,
6526"symlink(src, dst, target_is_directory=False)\n\n\
6527Create a symbolic link pointing to src named dst.\n\
6528target_is_directory is required if the target is to be interpreted as\n\
6529a directory.\n\
6530This function requires Windows 6.0 or greater, and raises a\n\
6531NotImplementedError otherwise.");
6532
6533static PyObject *
6534win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6535{
6536 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006537 PyObject *osrc, *odest;
6538 PyObject *usrc = NULL, *udest = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006539 wchar_t *wsrc, *wdest;
Brian Curtind40e6f72010-07-08 21:39:08 +00006540 int target_is_directory = 0;
6541 DWORD res;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006542
Brian Curtind40e6f72010-07-08 21:39:08 +00006543 if (!check_CreateSymbolicLinkW())
6544 {
6545 /* raise NotImplementedError */
6546 return PyErr_Format(PyExc_NotImplementedError,
6547 "CreateSymbolicLinkW not found");
6548 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006549 if (!PyArg_ParseTupleAndKeywords(
6550 args, kwargs, "OO|i:symlink", kwlist,
6551 &osrc, &odest, &target_is_directory))
Brian Curtind40e6f72010-07-08 21:39:08 +00006552 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006553
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006554 usrc = win32_decode_filename(osrc);
6555 if (!usrc)
6556 return NULL;
6557 udest = win32_decode_filename(odest);
6558 if (!udest)
6559 goto error;
6560
Brian Curtin3b4499c2010-12-28 14:31:47 +00006561 if (win32_can_symlink == 0)
6562 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6563
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006564 wsrc = PyUnicode_AsUnicode(usrc);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006565 if (wsrc == NULL)
6566 goto error;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006567 wdest = PyUnicode_AsUnicode(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006568 if (wsrc == NULL)
6569 goto error;
6570
Brian Curtind40e6f72010-07-08 21:39:08 +00006571 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006572 res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Brian Curtind40e6f72010-07-08 21:39:08 +00006573 Py_END_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006574
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006575 Py_DECREF(usrc);
6576 Py_DECREF(udest);
Brian Curtind40e6f72010-07-08 21:39:08 +00006577 if (!res)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006578 return win32_error_object("symlink", osrc);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006579
Brian Curtind40e6f72010-07-08 21:39:08 +00006580 Py_INCREF(Py_None);
6581 return Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006582
6583error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006584 Py_XDECREF(usrc);
6585 Py_XDECREF(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006586 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006587}
Brian Curtin52173d42010-12-02 18:29:18 +00006588#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006589
6590#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006591#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6592static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006593system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006594{
6595 ULONG value = 0;
6596
6597 Py_BEGIN_ALLOW_THREADS
6598 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6599 Py_END_ALLOW_THREADS
6600
6601 return value;
6602}
6603
6604static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006605posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006606{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006607 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 return Py_BuildValue("ddddd",
6609 (double)0 /* t.tms_utime / HZ */,
6610 (double)0 /* t.tms_stime / HZ */,
6611 (double)0 /* t.tms_cutime / HZ */,
6612 (double)0 /* t.tms_cstime / HZ */,
6613 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006614}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006615#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006616#define NEED_TICKS_PER_SECOND
6617static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006618static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006619posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006620{
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 struct tms t;
6622 clock_t c;
6623 errno = 0;
6624 c = times(&t);
6625 if (c == (clock_t) -1)
6626 return posix_error();
6627 return Py_BuildValue("ddddd",
6628 (double)t.tms_utime / ticks_per_second,
6629 (double)t.tms_stime / ticks_per_second,
6630 (double)t.tms_cutime / ticks_per_second,
6631 (double)t.tms_cstime / ticks_per_second,
6632 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006633}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006634#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006635#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006636
6637
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006638#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006639#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006640static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006641posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006642{
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 FILETIME create, exit, kernel, user;
6644 HANDLE hProc;
6645 hProc = GetCurrentProcess();
6646 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6647 /* The fields of a FILETIME structure are the hi and lo part
6648 of a 64-bit value expressed in 100 nanosecond units.
6649 1e7 is one second in such units; 1e-7 the inverse.
6650 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6651 */
6652 return Py_BuildValue(
6653 "ddddd",
6654 (double)(user.dwHighDateTime*429.4967296 +
6655 user.dwLowDateTime*1e-7),
6656 (double)(kernel.dwHighDateTime*429.4967296 +
6657 kernel.dwLowDateTime*1e-7),
6658 (double)0,
6659 (double)0,
6660 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006661}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006662#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006663
6664#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006665PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006666"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006667Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006668#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006670
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006671#ifdef HAVE_GETSID
6672PyDoc_STRVAR(posix_getsid__doc__,
6673"getsid(pid) -> sid\n\n\
6674Call the system call getsid().");
6675
6676static PyObject *
6677posix_getsid(PyObject *self, PyObject *args)
6678{
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 pid_t pid;
6680 int sid;
6681 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6682 return NULL;
6683 sid = getsid(pid);
6684 if (sid < 0)
6685 return posix_error();
6686 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006687}
6688#endif /* HAVE_GETSID */
6689
6690
Guido van Rossumb6775db1994-08-01 11:34:53 +00006691#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006692PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006693"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006694Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006695
Barry Warsaw53699e91996-12-10 23:23:01 +00006696static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006697posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006698{
Victor Stinner8c62be82010-05-06 00:08:46 +00006699 if (setsid() < 0)
6700 return posix_error();
6701 Py_INCREF(Py_None);
6702 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006703}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006704#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006705
Guido van Rossumb6775db1994-08-01 11:34:53 +00006706#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006708"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006710
Barry Warsaw53699e91996-12-10 23:23:01 +00006711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006712posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006713{
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 pid_t pid;
6715 int pgrp;
6716 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6717 return NULL;
6718 if (setpgid(pid, pgrp) < 0)
6719 return posix_error();
6720 Py_INCREF(Py_None);
6721 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006722}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006723#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006724
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006725
Guido van Rossumb6775db1994-08-01 11:34:53 +00006726#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006727PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006728"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006729Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006730
Barry Warsaw53699e91996-12-10 23:23:01 +00006731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006732posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006733{
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 int fd;
6735 pid_t pgid;
6736 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6737 return NULL;
6738 pgid = tcgetpgrp(fd);
6739 if (pgid < 0)
6740 return posix_error();
6741 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006742}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006743#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006744
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006745
Guido van Rossumb6775db1994-08-01 11:34:53 +00006746#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006747PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006748"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006749Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006750
Barry Warsaw53699e91996-12-10 23:23:01 +00006751static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006752posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006753{
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 int fd;
6755 pid_t pgid;
6756 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6757 return NULL;
6758 if (tcsetpgrp(fd, pgid) < 0)
6759 return posix_error();
6760 Py_INCREF(Py_None);
6761 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006762}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006763#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006764
Guido van Rossum687dd131993-05-17 08:34:16 +00006765/* Functions acting on file descriptors */
6766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006767PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006768"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006769Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006770
Barry Warsaw53699e91996-12-10 23:23:01 +00006771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006772posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006773{
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 PyObject *ofile;
6775 char *file;
6776 int flag;
6777 int mode = 0777;
6778 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006779
6780#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006781 PyObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006782 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02006783 wchar_t *wpath = PyUnicode_AsUnicode(po);
6784 if (wpath == NULL)
6785 return NULL;
6786
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006788 fd = _wopen(wpath, flag, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 Py_END_ALLOW_THREADS
6790 if (fd < 0)
6791 return posix_error();
6792 return PyLong_FromLong((long)fd);
6793 }
6794 /* Drop the argument parsing error as narrow strings
6795 are also valid. */
6796 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006797#endif
6798
Victor Stinner26de69d2011-06-17 15:15:38 +02006799 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 PyUnicode_FSConverter, &ofile,
6801 &flag, &mode))
6802 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006803#ifdef MS_WINDOWS
6804 if (win32_warn_bytes_api()) {
6805 Py_DECREF(ofile);
6806 return NULL;
6807 }
6808#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 file = PyBytes_AsString(ofile);
6810 Py_BEGIN_ALLOW_THREADS
6811 fd = open(file, flag, mode);
6812 Py_END_ALLOW_THREADS
6813 if (fd < 0)
6814 return posix_error_with_allocated_filename(ofile);
6815 Py_DECREF(ofile);
6816 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006817}
6818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006819
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006820PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006821"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006822Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006823
Barry Warsaw53699e91996-12-10 23:23:01 +00006824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006825posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006826{
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 int fd, res;
6828 if (!PyArg_ParseTuple(args, "i:close", &fd))
6829 return NULL;
6830 if (!_PyVerify_fd(fd))
6831 return posix_error();
6832 Py_BEGIN_ALLOW_THREADS
6833 res = close(fd);
6834 Py_END_ALLOW_THREADS
6835 if (res < 0)
6836 return posix_error();
6837 Py_INCREF(Py_None);
6838 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006839}
6840
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006841
Victor Stinner8c62be82010-05-06 00:08:46 +00006842PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006843"closerange(fd_low, fd_high)\n\n\
6844Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6845
6846static PyObject *
6847posix_closerange(PyObject *self, PyObject *args)
6848{
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 int fd_from, fd_to, i;
6850 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6851 return NULL;
6852 Py_BEGIN_ALLOW_THREADS
6853 for (i = fd_from; i < fd_to; i++)
6854 if (_PyVerify_fd(i))
6855 close(i);
6856 Py_END_ALLOW_THREADS
6857 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006858}
6859
6860
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006861PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006862"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006863Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006864
Barry Warsaw53699e91996-12-10 23:23:01 +00006865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006866posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006867{
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 int fd;
6869 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6870 return NULL;
6871 if (!_PyVerify_fd(fd))
6872 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 if (fd < 0)
6875 return posix_error();
6876 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006877}
6878
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006879
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006880PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006881"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006882Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006883
Barry Warsaw53699e91996-12-10 23:23:01 +00006884static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006885posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006886{
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 int fd, fd2, res;
6888 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6889 return NULL;
6890 if (!_PyVerify_fd_dup2(fd, fd2))
6891 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 if (res < 0)
6894 return posix_error();
6895 Py_INCREF(Py_None);
6896 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006897}
6898
Ross Lagerwall7807c352011-03-17 20:20:30 +02006899#ifdef HAVE_LOCKF
6900PyDoc_STRVAR(posix_lockf__doc__,
6901"lockf(fd, cmd, len)\n\n\
6902Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6903fd is an open file descriptor.\n\
6904cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6905F_TEST.\n\
6906len specifies the section of the file to lock.");
6907
6908static PyObject *
6909posix_lockf(PyObject *self, PyObject *args)
6910{
6911 int fd, cmd, res;
6912 off_t len;
6913 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6914 &fd, &cmd, _parse_off_t, &len))
6915 return NULL;
6916
6917 Py_BEGIN_ALLOW_THREADS
6918 res = lockf(fd, cmd, len);
6919 Py_END_ALLOW_THREADS
6920
6921 if (res < 0)
6922 return posix_error();
6923
6924 Py_RETURN_NONE;
6925}
6926#endif
6927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006928
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006929PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006930"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01006931Set the current position of a file descriptor.\n\
6932Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006933
Barry Warsaw53699e91996-12-10 23:23:01 +00006934static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006935posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006936{
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006938#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006939 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006940#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006942#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02006943 PyObject *posobj;
6944 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006946#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6948 switch (how) {
6949 case 0: how = SEEK_SET; break;
6950 case 1: how = SEEK_CUR; break;
6951 case 2: how = SEEK_END; break;
6952 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006953#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006954
Ross Lagerwall8e749672011-03-17 21:54:07 +02006955#if !defined(HAVE_LARGEFILE_SUPPORT)
6956 pos = PyLong_AsLong(posobj);
6957#else
6958 pos = PyLong_AsLongLong(posobj);
6959#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 if (PyErr_Occurred())
6961 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006962
Victor Stinner8c62be82010-05-06 00:08:46 +00006963 if (!_PyVerify_fd(fd))
6964 return posix_error();
6965 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006966#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006968#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006969 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006970#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 Py_END_ALLOW_THREADS
6972 if (res < 0)
6973 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006974
6975#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006977#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006978 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006979#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006980}
6981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006983PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006984"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006985Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006986
Barry Warsaw53699e91996-12-10 23:23:01 +00006987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006988posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006989{
Victor Stinner8c62be82010-05-06 00:08:46 +00006990 int fd, size;
6991 Py_ssize_t n;
6992 PyObject *buffer;
6993 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6994 return NULL;
6995 if (size < 0) {
6996 errno = EINVAL;
6997 return posix_error();
6998 }
6999 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7000 if (buffer == NULL)
7001 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007002 if (!_PyVerify_fd(fd)) {
7003 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007005 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 Py_BEGIN_ALLOW_THREADS
7007 n = read(fd, PyBytes_AS_STRING(buffer), size);
7008 Py_END_ALLOW_THREADS
7009 if (n < 0) {
7010 Py_DECREF(buffer);
7011 return posix_error();
7012 }
7013 if (n != size)
7014 _PyBytes_Resize(&buffer, n);
7015 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007016}
7017
Ross Lagerwall7807c352011-03-17 20:20:30 +02007018#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7019 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007020static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007021iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7022{
7023 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007024 Py_ssize_t blen, total = 0;
7025
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007026 *iov = PyMem_New(struct iovec, cnt);
7027 if (*iov == NULL) {
7028 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007029 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007030 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007031
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007032 *buf = PyMem_New(Py_buffer, cnt);
7033 if (*buf == NULL) {
7034 PyMem_Del(*iov);
7035 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007036 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007037 }
7038
7039 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007040 PyObject *item = PySequence_GetItem(seq, i);
7041 if (item == NULL)
7042 goto fail;
7043 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7044 Py_DECREF(item);
7045 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007046 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007047 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007048 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007049 blen = (*buf)[i].len;
7050 (*iov)[i].iov_len = blen;
7051 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007052 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007053 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007054
7055fail:
7056 PyMem_Del(*iov);
7057 for (j = 0; j < i; j++) {
7058 PyBuffer_Release(&(*buf)[j]);
7059 }
7060 PyMem_Del(*buf);
7061 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007062}
7063
7064static void
7065iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7066{
7067 int i;
7068 PyMem_Del(iov);
7069 for (i = 0; i < cnt; i++) {
7070 PyBuffer_Release(&buf[i]);
7071 }
7072 PyMem_Del(buf);
7073}
7074#endif
7075
Ross Lagerwall7807c352011-03-17 20:20:30 +02007076#ifdef HAVE_READV
7077PyDoc_STRVAR(posix_readv__doc__,
7078"readv(fd, buffers) -> bytesread\n\n\
7079Read from a file descriptor into a number of writable buffers. buffers\n\
7080is an arbitrary sequence of writable buffers.\n\
7081Returns the total number of bytes read.");
7082
7083static PyObject *
7084posix_readv(PyObject *self, PyObject *args)
7085{
7086 int fd, cnt;
7087 Py_ssize_t n;
7088 PyObject *seq;
7089 struct iovec *iov;
7090 Py_buffer *buf;
7091
7092 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7093 return NULL;
7094 if (!PySequence_Check(seq)) {
7095 PyErr_SetString(PyExc_TypeError,
7096 "readv() arg 2 must be a sequence");
7097 return NULL;
7098 }
7099 cnt = PySequence_Size(seq);
7100
7101 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7102 return NULL;
7103
7104 Py_BEGIN_ALLOW_THREADS
7105 n = readv(fd, iov, cnt);
7106 Py_END_ALLOW_THREADS
7107
7108 iov_cleanup(iov, buf, cnt);
7109 return PyLong_FromSsize_t(n);
7110}
7111#endif
7112
7113#ifdef HAVE_PREAD
7114PyDoc_STRVAR(posix_pread__doc__,
7115"pread(fd, buffersize, offset) -> string\n\n\
7116Read from a file descriptor, fd, at a position of offset. It will read up\n\
7117to buffersize number of bytes. The file offset remains unchanged.");
7118
7119static PyObject *
7120posix_pread(PyObject *self, PyObject *args)
7121{
7122 int fd, size;
7123 off_t offset;
7124 Py_ssize_t n;
7125 PyObject *buffer;
7126 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7127 return NULL;
7128
7129 if (size < 0) {
7130 errno = EINVAL;
7131 return posix_error();
7132 }
7133 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7134 if (buffer == NULL)
7135 return NULL;
7136 if (!_PyVerify_fd(fd)) {
7137 Py_DECREF(buffer);
7138 return posix_error();
7139 }
7140 Py_BEGIN_ALLOW_THREADS
7141 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7142 Py_END_ALLOW_THREADS
7143 if (n < 0) {
7144 Py_DECREF(buffer);
7145 return posix_error();
7146 }
7147 if (n != size)
7148 _PyBytes_Resize(&buffer, n);
7149 return buffer;
7150}
7151#endif
7152
7153PyDoc_STRVAR(posix_write__doc__,
7154"write(fd, string) -> byteswritten\n\n\
7155Write a string to a file descriptor.");
7156
7157static PyObject *
7158posix_write(PyObject *self, PyObject *args)
7159{
7160 Py_buffer pbuf;
7161 int fd;
7162 Py_ssize_t size, len;
7163
7164 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7165 return NULL;
7166 if (!_PyVerify_fd(fd)) {
7167 PyBuffer_Release(&pbuf);
7168 return posix_error();
7169 }
7170 len = pbuf.len;
7171 Py_BEGIN_ALLOW_THREADS
7172#if defined(MS_WIN64) || defined(MS_WINDOWS)
7173 if (len > INT_MAX)
7174 len = INT_MAX;
7175 size = write(fd, pbuf.buf, (int)len);
7176#else
7177 size = write(fd, pbuf.buf, len);
7178#endif
7179 Py_END_ALLOW_THREADS
7180 PyBuffer_Release(&pbuf);
7181 if (size < 0)
7182 return posix_error();
7183 return PyLong_FromSsize_t(size);
7184}
7185
7186#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007187PyDoc_STRVAR(posix_sendfile__doc__,
7188"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7189sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7190 -> byteswritten\n\
7191Copy nbytes bytes from file descriptor in to file descriptor out.");
7192
7193static PyObject *
7194posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7195{
7196 int in, out;
7197 Py_ssize_t ret;
7198 off_t offset;
7199
7200#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7201#ifndef __APPLE__
7202 Py_ssize_t len;
7203#endif
7204 PyObject *headers = NULL, *trailers = NULL;
7205 Py_buffer *hbuf, *tbuf;
7206 off_t sbytes;
7207 struct sf_hdtr sf;
7208 int flags = 0;
7209 sf.headers = NULL;
7210 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007211 static char *keywords[] = {"out", "in",
7212 "offset", "count",
7213 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007214
7215#ifdef __APPLE__
7216 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007217 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007218#else
7219 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007220 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007221#endif
7222 &headers, &trailers, &flags))
7223 return NULL;
7224 if (headers != NULL) {
7225 if (!PySequence_Check(headers)) {
7226 PyErr_SetString(PyExc_TypeError,
7227 "sendfile() headers must be a sequence or None");
7228 return NULL;
7229 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007230 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007231 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007232 if (sf.hdr_cnt > 0 &&
7233 !(i = iov_setup(&(sf.headers), &hbuf,
7234 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007235 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007236#ifdef __APPLE__
7237 sbytes += i;
7238#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007239 }
7240 }
7241 if (trailers != NULL) {
7242 if (!PySequence_Check(trailers)) {
7243 PyErr_SetString(PyExc_TypeError,
7244 "sendfile() trailers must be a sequence or None");
7245 return NULL;
7246 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007247 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007248 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007249 if (sf.trl_cnt > 0 &&
7250 !(i = iov_setup(&(sf.trailers), &tbuf,
7251 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007252 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007253#ifdef __APPLE__
7254 sbytes += i;
7255#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007256 }
7257 }
7258
7259 Py_BEGIN_ALLOW_THREADS
7260#ifdef __APPLE__
7261 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7262#else
7263 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7264#endif
7265 Py_END_ALLOW_THREADS
7266
7267 if (sf.headers != NULL)
7268 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7269 if (sf.trailers != NULL)
7270 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7271
7272 if (ret < 0) {
7273 if ((errno == EAGAIN) || (errno == EBUSY)) {
7274 if (sbytes != 0) {
7275 // some data has been sent
7276 goto done;
7277 }
7278 else {
7279 // no data has been sent; upper application is supposed
7280 // to retry on EAGAIN or EBUSY
7281 return posix_error();
7282 }
7283 }
7284 return posix_error();
7285 }
7286 goto done;
7287
7288done:
7289 #if !defined(HAVE_LARGEFILE_SUPPORT)
7290 return Py_BuildValue("l", sbytes);
7291 #else
7292 return Py_BuildValue("L", sbytes);
7293 #endif
7294
7295#else
7296 Py_ssize_t count;
7297 PyObject *offobj;
7298 static char *keywords[] = {"out", "in",
7299 "offset", "count", NULL};
7300 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7301 keywords, &out, &in, &offobj, &count))
7302 return NULL;
7303#ifdef linux
7304 if (offobj == Py_None) {
7305 Py_BEGIN_ALLOW_THREADS
7306 ret = sendfile(out, in, NULL, count);
7307 Py_END_ALLOW_THREADS
7308 if (ret < 0)
7309 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007310 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007311 }
7312#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007313 if (!_parse_off_t(offobj, &offset))
7314 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007315 Py_BEGIN_ALLOW_THREADS
7316 ret = sendfile(out, in, &offset, count);
7317 Py_END_ALLOW_THREADS
7318 if (ret < 0)
7319 return posix_error();
7320 return Py_BuildValue("n", ret);
7321#endif
7322}
7323#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007324
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007325PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007326"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007327Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007328
Barry Warsaw53699e91996-12-10 23:23:01 +00007329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007330posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007331{
Victor Stinner8c62be82010-05-06 00:08:46 +00007332 int fd;
7333 STRUCT_STAT st;
7334 int res;
7335 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
7336 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007337#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007338 /* on OpenVMS we must ensure that all bytes are written to the file */
7339 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007340#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007341 if (!_PyVerify_fd(fd))
7342 return posix_error();
7343 Py_BEGIN_ALLOW_THREADS
7344 res = FSTAT(fd, &st);
7345 Py_END_ALLOW_THREADS
7346 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007347#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007348 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007349#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007350 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007351#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007352 }
Tim Peters5aa91602002-01-30 05:46:57 +00007353
Victor Stinner8c62be82010-05-06 00:08:46 +00007354 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007355}
7356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007357PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007358"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007359Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007360connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007361
7362static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007363posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007364{
Victor Stinner8c62be82010-05-06 00:08:46 +00007365 int fd;
7366 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7367 return NULL;
7368 if (!_PyVerify_fd(fd))
7369 return PyBool_FromLong(0);
7370 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007371}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007372
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007373#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007374PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007375"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007376Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007377
Barry Warsaw53699e91996-12-10 23:23:01 +00007378static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007379posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007380{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007381#if defined(PYOS_OS2)
7382 HFILE read, write;
7383 APIRET rc;
7384
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007385 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007386 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007387 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007388
7389 return Py_BuildValue("(ii)", read, write);
7390#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007391#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007392 int fds[2];
7393 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007394 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007395 if (res != 0)
7396 return posix_error();
7397 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007398#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007399 HANDLE read, write;
7400 int read_fd, write_fd;
7401 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007402 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007403 if (!ok)
7404 return win32_error("CreatePipe", NULL);
7405 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7406 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7407 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007408#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007409#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007410}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007411#endif /* HAVE_PIPE */
7412
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007413#ifdef HAVE_PIPE2
7414PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007415"pipe2(flags) -> (read_end, write_end)\n\n\
7416Create a pipe with flags set atomically.\n\
7417flags can be constructed by ORing together one or more of these values:\n\
7418O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007419");
7420
7421static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007422posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007423{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007424 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007425 int fds[2];
7426 int res;
7427
Charles-François Natali368f34b2011-06-06 19:49:47 +02007428 flags = PyLong_AsLong(arg);
7429 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007430 return NULL;
7431
7432 res = pipe2(fds, flags);
7433 if (res != 0)
7434 return posix_error();
7435 return Py_BuildValue("(ii)", fds[0], fds[1]);
7436}
7437#endif /* HAVE_PIPE2 */
7438
Ross Lagerwall7807c352011-03-17 20:20:30 +02007439#ifdef HAVE_WRITEV
7440PyDoc_STRVAR(posix_writev__doc__,
7441"writev(fd, buffers) -> byteswritten\n\n\
7442Write the contents of buffers to a file descriptor, where buffers is an\n\
7443arbitrary sequence of buffers.\n\
7444Returns the total bytes written.");
7445
7446static PyObject *
7447posix_writev(PyObject *self, PyObject *args)
7448{
7449 int fd, cnt;
7450 Py_ssize_t res;
7451 PyObject *seq;
7452 struct iovec *iov;
7453 Py_buffer *buf;
7454 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7455 return NULL;
7456 if (!PySequence_Check(seq)) {
7457 PyErr_SetString(PyExc_TypeError,
7458 "writev() arg 2 must be a sequence");
7459 return NULL;
7460 }
7461 cnt = PySequence_Size(seq);
7462
7463 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7464 return NULL;
7465 }
7466
7467 Py_BEGIN_ALLOW_THREADS
7468 res = writev(fd, iov, cnt);
7469 Py_END_ALLOW_THREADS
7470
7471 iov_cleanup(iov, buf, cnt);
7472 return PyLong_FromSsize_t(res);
7473}
7474#endif
7475
7476#ifdef HAVE_PWRITE
7477PyDoc_STRVAR(posix_pwrite__doc__,
7478"pwrite(fd, string, offset) -> byteswritten\n\n\
7479Write string to a file descriptor, fd, from offset, leaving the file\n\
7480offset unchanged.");
7481
7482static PyObject *
7483posix_pwrite(PyObject *self, PyObject *args)
7484{
7485 Py_buffer pbuf;
7486 int fd;
7487 off_t offset;
7488 Py_ssize_t size;
7489
7490 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7491 return NULL;
7492
7493 if (!_PyVerify_fd(fd)) {
7494 PyBuffer_Release(&pbuf);
7495 return posix_error();
7496 }
7497 Py_BEGIN_ALLOW_THREADS
7498 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7499 Py_END_ALLOW_THREADS
7500 PyBuffer_Release(&pbuf);
7501 if (size < 0)
7502 return posix_error();
7503 return PyLong_FromSsize_t(size);
7504}
7505#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007506
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007507#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007508PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007509"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007510Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007511
Barry Warsaw53699e91996-12-10 23:23:01 +00007512static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007513posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007514{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007515 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007516 char *filename;
7517 int mode = 0666;
7518 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007519 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7520 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007521 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007522 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007523 Py_BEGIN_ALLOW_THREADS
7524 res = mkfifo(filename, mode);
7525 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007526 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 if (res < 0)
7528 return posix_error();
7529 Py_INCREF(Py_None);
7530 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007531}
7532#endif
7533
7534
Neal Norwitz11690112002-07-30 01:08:28 +00007535#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007536PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007537"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007538Create a filesystem node (file, device special file or named pipe)\n\
7539named filename. mode specifies both the permissions to use and the\n\
7540type of node to be created, being combined (bitwise OR) with one of\n\
7541S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007542device defines the newly created device special file (probably using\n\
7543os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007544
7545
7546static PyObject *
7547posix_mknod(PyObject *self, PyObject *args)
7548{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007549 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007550 char *filename;
7551 int mode = 0600;
7552 int device = 0;
7553 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007554 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7555 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007556 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007557 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007558 Py_BEGIN_ALLOW_THREADS
7559 res = mknod(filename, mode, device);
7560 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007561 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 if (res < 0)
7563 return posix_error();
7564 Py_INCREF(Py_None);
7565 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007566}
7567#endif
7568
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007569#ifdef HAVE_DEVICE_MACROS
7570PyDoc_STRVAR(posix_major__doc__,
7571"major(device) -> major number\n\
7572Extracts a device major number from a raw device number.");
7573
7574static PyObject *
7575posix_major(PyObject *self, PyObject *args)
7576{
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 int device;
7578 if (!PyArg_ParseTuple(args, "i:major", &device))
7579 return NULL;
7580 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007581}
7582
7583PyDoc_STRVAR(posix_minor__doc__,
7584"minor(device) -> minor number\n\
7585Extracts a device minor number from a raw device number.");
7586
7587static PyObject *
7588posix_minor(PyObject *self, PyObject *args)
7589{
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 int device;
7591 if (!PyArg_ParseTuple(args, "i:minor", &device))
7592 return NULL;
7593 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007594}
7595
7596PyDoc_STRVAR(posix_makedev__doc__,
7597"makedev(major, minor) -> device number\n\
7598Composes a raw device number from the major and minor device numbers.");
7599
7600static PyObject *
7601posix_makedev(PyObject *self, PyObject *args)
7602{
Victor Stinner8c62be82010-05-06 00:08:46 +00007603 int major, minor;
7604 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7605 return NULL;
7606 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007607}
7608#endif /* device macros */
7609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007611#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007612PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007613"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007614Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007615
Barry Warsaw53699e91996-12-10 23:23:01 +00007616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007617posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007618{
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 int fd;
7620 off_t length;
7621 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007622
Ross Lagerwall7807c352011-03-17 20:20:30 +02007623 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007624 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007625
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 Py_BEGIN_ALLOW_THREADS
7627 res = ftruncate(fd, length);
7628 Py_END_ALLOW_THREADS
7629 if (res < 0)
7630 return posix_error();
7631 Py_INCREF(Py_None);
7632 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007633}
7634#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007635
Ross Lagerwall7807c352011-03-17 20:20:30 +02007636#ifdef HAVE_TRUNCATE
7637PyDoc_STRVAR(posix_truncate__doc__,
7638"truncate(path, length)\n\n\
7639Truncate the file given by path to length bytes.");
7640
7641static PyObject *
7642posix_truncate(PyObject *self, PyObject *args)
7643{
7644 PyObject *opath;
7645 const char *path;
7646 off_t length;
7647 int res;
7648
7649 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7650 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7651 return NULL;
7652 path = PyBytes_AsString(opath);
7653
7654 Py_BEGIN_ALLOW_THREADS
7655 res = truncate(path, length);
7656 Py_END_ALLOW_THREADS
7657 Py_DECREF(opath);
7658 if (res < 0)
7659 return posix_error();
7660 Py_RETURN_NONE;
7661}
7662#endif
7663
7664#ifdef HAVE_POSIX_FALLOCATE
7665PyDoc_STRVAR(posix_posix_fallocate__doc__,
7666"posix_fallocate(fd, offset, len)\n\n\
7667Ensures that enough disk space is allocated for the file specified by fd\n\
7668starting from offset and continuing for len bytes.");
7669
7670static PyObject *
7671posix_posix_fallocate(PyObject *self, PyObject *args)
7672{
7673 off_t len, offset;
7674 int res, fd;
7675
7676 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7677 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7678 return NULL;
7679
7680 Py_BEGIN_ALLOW_THREADS
7681 res = posix_fallocate(fd, offset, len);
7682 Py_END_ALLOW_THREADS
7683 if (res != 0) {
7684 errno = res;
7685 return posix_error();
7686 }
7687 Py_RETURN_NONE;
7688}
7689#endif
7690
7691#ifdef HAVE_POSIX_FADVISE
7692PyDoc_STRVAR(posix_posix_fadvise__doc__,
7693"posix_fadvise(fd, offset, len, advice)\n\n\
7694Announces an intention to access data in a specific pattern thus allowing\n\
7695the kernel to make optimizations.\n\
7696The advice applies to the region of the file specified by fd starting at\n\
7697offset and continuing for len bytes.\n\
7698advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7699POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7700POSIX_FADV_DONTNEED.");
7701
7702static PyObject *
7703posix_posix_fadvise(PyObject *self, PyObject *args)
7704{
7705 off_t len, offset;
7706 int res, fd, advice;
7707
7708 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7709 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7710 return NULL;
7711
7712 Py_BEGIN_ALLOW_THREADS
7713 res = posix_fadvise(fd, offset, len, advice);
7714 Py_END_ALLOW_THREADS
7715 if (res != 0) {
7716 errno = res;
7717 return posix_error();
7718 }
7719 Py_RETURN_NONE;
7720}
7721#endif
7722
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007723#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007724PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007725"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007726Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007727
Fred Drake762e2061999-08-26 17:23:54 +00007728/* Save putenv() parameters as values here, so we can collect them when they
7729 * get re-set with another call for the same key. */
7730static PyObject *posix_putenv_garbage;
7731
Tim Peters5aa91602002-01-30 05:46:57 +00007732static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007733posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007734{
Victor Stinner84ae1182010-05-06 22:05:07 +00007735 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007736#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01007737 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007738 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01007739
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007741 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01007742 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007744
Victor Stinner65170952011-11-22 22:16:17 +01007745 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00007746 if (newstr == NULL) {
7747 PyErr_NoMemory();
7748 goto error;
7749 }
Victor Stinner65170952011-11-22 22:16:17 +01007750 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
7751 PyErr_Format(PyExc_ValueError,
7752 "the environment variable is longer than %u characters",
7753 _MAX_ENV);
7754 goto error;
7755 }
7756
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02007758 if (newenv == NULL)
7759 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007762 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007764#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007765 PyObject *os1, *os2;
7766 char *s1, *s2;
7767 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007768
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007769 if (!PyArg_ParseTuple(args,
7770 "O&O&:putenv",
7771 PyUnicode_FSConverter, &os1,
7772 PyUnicode_FSConverter, &os2))
7773 return NULL;
7774 s1 = PyBytes_AsString(os1);
7775 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00007776
Victor Stinner65170952011-11-22 22:16:17 +01007777 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007778 if (newstr == NULL) {
7779 PyErr_NoMemory();
7780 goto error;
7781 }
7782
Victor Stinner8c62be82010-05-06 00:08:46 +00007783 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007786 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007787 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007788#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007789
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 /* Install the first arg and newstr in posix_putenv_garbage;
7791 * this will cause previous value to be collected. This has to
7792 * happen after the real putenv() call because the old value
7793 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01007794 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 /* really not much we can do; just leak */
7796 PyErr_Clear();
7797 }
7798 else {
7799 Py_DECREF(newstr);
7800 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007801
Martin v. Löwis011e8422009-05-05 04:43:17 +00007802#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 Py_DECREF(os1);
7804 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007805#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007806 Py_RETURN_NONE;
7807
7808error:
7809#ifndef MS_WINDOWS
7810 Py_DECREF(os1);
7811 Py_DECREF(os2);
7812#endif
7813 Py_XDECREF(newstr);
7814 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00007815}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007816#endif /* putenv */
7817
Guido van Rossumc524d952001-10-19 01:31:59 +00007818#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007819PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007820"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007821Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007822
7823static PyObject *
7824posix_unsetenv(PyObject *self, PyObject *args)
7825{
Victor Stinner65170952011-11-22 22:16:17 +01007826 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01007827#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01007828 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01007829#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007830
7831 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00007832
Victor Stinner65170952011-11-22 22:16:17 +01007833 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00007834 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007835
Victor Stinner984890f2011-11-24 13:53:38 +01007836#ifdef HAVE_BROKEN_UNSETENV
7837 unsetenv(PyBytes_AS_STRING(name));
7838#else
Victor Stinner65170952011-11-22 22:16:17 +01007839 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007840 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06007841 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01007842 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007843 }
Victor Stinner984890f2011-11-24 13:53:38 +01007844#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007845
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 /* Remove the key from posix_putenv_garbage;
7847 * this will cause it to be collected. This has to
7848 * happen after the real unsetenv() call because the
7849 * old value was still accessible until then.
7850 */
Victor Stinner65170952011-11-22 22:16:17 +01007851 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 /* really not much we can do; just leak */
7853 PyErr_Clear();
7854 }
Victor Stinner65170952011-11-22 22:16:17 +01007855 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00007856 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007857}
7858#endif /* unsetenv */
7859
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007860PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007861"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007862Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007863
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007865posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007866{
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 int code;
7868 char *message;
7869 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7870 return NULL;
7871 message = strerror(code);
7872 if (message == NULL) {
7873 PyErr_SetString(PyExc_ValueError,
7874 "strerror() argument out of range");
7875 return NULL;
7876 }
Victor Stinner1b579672011-12-17 05:47:23 +01007877 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007878}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007879
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007880
Guido van Rossumc9641791998-08-04 15:26:23 +00007881#ifdef HAVE_SYS_WAIT_H
7882
Fred Drake106c1a02002-04-23 15:58:02 +00007883#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007884PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007885"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007886Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007887
7888static PyObject *
7889posix_WCOREDUMP(PyObject *self, PyObject *args)
7890{
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 WAIT_TYPE status;
7892 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007893
Victor Stinner8c62be82010-05-06 00:08:46 +00007894 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7895 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007896
Victor Stinner8c62be82010-05-06 00:08:46 +00007897 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007898}
7899#endif /* WCOREDUMP */
7900
7901#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007902PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007903"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007904Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007905job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007906
7907static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007908posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007909{
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 WAIT_TYPE status;
7911 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007912
Victor Stinner8c62be82010-05-06 00:08:46 +00007913 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7914 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007915
Victor Stinner8c62be82010-05-06 00:08:46 +00007916 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007917}
7918#endif /* WIFCONTINUED */
7919
Guido van Rossumc9641791998-08-04 15:26:23 +00007920#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007921PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007922"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007923Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007924
7925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007926posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007927{
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 WAIT_TYPE status;
7929 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007930
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7932 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007933
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007935}
7936#endif /* WIFSTOPPED */
7937
7938#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007939PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007940"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007941Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007942
7943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007944posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007945{
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 WAIT_TYPE status;
7947 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007948
Victor Stinner8c62be82010-05-06 00:08:46 +00007949 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7950 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007951
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007953}
7954#endif /* WIFSIGNALED */
7955
7956#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007957PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007958"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007959Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007960system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007961
7962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007963posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007964{
Victor Stinner8c62be82010-05-06 00:08:46 +00007965 WAIT_TYPE status;
7966 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007967
Victor Stinner8c62be82010-05-06 00:08:46 +00007968 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7969 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007970
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007972}
7973#endif /* WIFEXITED */
7974
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007975#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007976PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007977"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007978Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007979
7980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007981posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007982{
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 WAIT_TYPE status;
7984 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007985
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7987 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007988
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007990}
7991#endif /* WEXITSTATUS */
7992
7993#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007994PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007995"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007996Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007997value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007998
7999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008000posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008001{
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 WAIT_TYPE status;
8003 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008004
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8006 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008007
Victor Stinner8c62be82010-05-06 00:08:46 +00008008 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008009}
8010#endif /* WTERMSIG */
8011
8012#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008013PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008014"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008015Return the signal that stopped the process that provided\n\
8016the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008017
8018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008019posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008020{
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 WAIT_TYPE status;
8022 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008023
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8025 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008026
Victor Stinner8c62be82010-05-06 00:08:46 +00008027 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008028}
8029#endif /* WSTOPSIG */
8030
8031#endif /* HAVE_SYS_WAIT_H */
8032
8033
Thomas Wouters477c8d52006-05-27 19:21:47 +00008034#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008035#ifdef _SCO_DS
8036/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8037 needed definitions in sys/statvfs.h */
8038#define _SVID3
8039#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008040#include <sys/statvfs.h>
8041
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008042static PyObject*
8043_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8045 if (v == NULL)
8046 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008047
8048#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008049 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8050 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8051 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8052 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8053 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8054 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8055 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8056 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8057 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8058 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008059#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008060 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8061 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8062 PyStructSequence_SET_ITEM(v, 2,
8063 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8064 PyStructSequence_SET_ITEM(v, 3,
8065 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8066 PyStructSequence_SET_ITEM(v, 4,
8067 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8068 PyStructSequence_SET_ITEM(v, 5,
8069 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8070 PyStructSequence_SET_ITEM(v, 6,
8071 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8072 PyStructSequence_SET_ITEM(v, 7,
8073 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8074 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8075 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008076#endif
8077
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008079}
8080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008081PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008082"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008083Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008084
8085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008086posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008087{
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 int fd, res;
8089 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008090
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8092 return NULL;
8093 Py_BEGIN_ALLOW_THREADS
8094 res = fstatvfs(fd, &st);
8095 Py_END_ALLOW_THREADS
8096 if (res != 0)
8097 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008098
Victor Stinner8c62be82010-05-06 00:08:46 +00008099 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008100}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008101#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008102
8103
Thomas Wouters477c8d52006-05-27 19:21:47 +00008104#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008105#include <sys/statvfs.h>
8106
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008107PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008108"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008109Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008110
8111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008112posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008113{
Victor Stinner6fa67772011-09-20 04:04:33 +02008114 PyObject *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 int res;
8116 struct statvfs st;
Victor Stinner6fa67772011-09-20 04:04:33 +02008117 if (!PyArg_ParseTuple(args, "O&:statvfs", PyUnicode_FSConverter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00008118 return NULL;
8119 Py_BEGIN_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008120 res = statvfs(PyBytes_AS_STRING(path), &st);
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 Py_END_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008122 if (res != 0) {
8123 posix_error_with_filename(PyBytes_AS_STRING(path));
8124 Py_DECREF(path);
8125 return NULL;
8126 }
8127 Py_DECREF(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008128
Victor Stinner8c62be82010-05-06 00:08:46 +00008129 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008130}
8131#endif /* HAVE_STATVFS */
8132
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008133#ifdef MS_WINDOWS
8134PyDoc_STRVAR(win32__getdiskusage__doc__,
8135"_getdiskusage(path) -> (total, free)\n\n\
8136Return disk usage statistics about the given path as (total, free) tuple.");
8137
8138static PyObject *
8139win32__getdiskusage(PyObject *self, PyObject *args)
8140{
8141 BOOL retval;
8142 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008143 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008144
Victor Stinner6139c1b2011-11-09 22:14:14 +01008145 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008146 return NULL;
8147
8148 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008149 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008150 Py_END_ALLOW_THREADS
8151 if (retval == 0)
8152 return PyErr_SetFromWindowsErr(0);
8153
8154 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8155}
8156#endif
8157
8158
Fred Drakec9680921999-12-13 16:37:25 +00008159/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8160 * It maps strings representing configuration variable names to
8161 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008162 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008163 * rarely-used constants. There are three separate tables that use
8164 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008165 *
8166 * This code is always included, even if none of the interfaces that
8167 * need it are included. The #if hackery needed to avoid it would be
8168 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008169 */
8170struct constdef {
8171 char *name;
8172 long value;
8173};
8174
Fred Drake12c6e2d1999-12-14 21:25:03 +00008175static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008176conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008177 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008178{
Christian Heimes217cfd12007-12-02 14:31:20 +00008179 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008180 *valuep = PyLong_AS_LONG(arg);
8181 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008182 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008183 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008184 /* look up the value in the table using a binary search */
8185 size_t lo = 0;
8186 size_t mid;
8187 size_t hi = tablesize;
8188 int cmp;
8189 const char *confname;
8190 if (!PyUnicode_Check(arg)) {
8191 PyErr_SetString(PyExc_TypeError,
8192 "configuration names must be strings or integers");
8193 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008195 confname = _PyUnicode_AsString(arg);
8196 if (confname == NULL)
8197 return 0;
8198 while (lo < hi) {
8199 mid = (lo + hi) / 2;
8200 cmp = strcmp(confname, table[mid].name);
8201 if (cmp < 0)
8202 hi = mid;
8203 else if (cmp > 0)
8204 lo = mid + 1;
8205 else {
8206 *valuep = table[mid].value;
8207 return 1;
8208 }
8209 }
8210 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8211 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008212 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008213}
8214
8215
8216#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8217static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008218#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008219 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008220#endif
8221#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008222 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008223#endif
Fred Drakec9680921999-12-13 16:37:25 +00008224#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008225 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008226#endif
8227#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008228 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008229#endif
8230#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008231 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008232#endif
8233#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008234 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008235#endif
8236#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008237 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008238#endif
8239#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008240 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008241#endif
8242#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008243 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008244#endif
8245#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008246 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008247#endif
8248#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008249 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008250#endif
8251#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008253#endif
8254#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008255 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008256#endif
8257#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008258 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008259#endif
8260#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008261 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008262#endif
8263#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008264 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008265#endif
8266#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008267 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008268#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008269#ifdef _PC_ACL_ENABLED
8270 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8271#endif
8272#ifdef _PC_MIN_HOLE_SIZE
8273 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8274#endif
8275#ifdef _PC_ALLOC_SIZE_MIN
8276 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8277#endif
8278#ifdef _PC_REC_INCR_XFER_SIZE
8279 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8280#endif
8281#ifdef _PC_REC_MAX_XFER_SIZE
8282 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8283#endif
8284#ifdef _PC_REC_MIN_XFER_SIZE
8285 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8286#endif
8287#ifdef _PC_REC_XFER_ALIGN
8288 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8289#endif
8290#ifdef _PC_SYMLINK_MAX
8291 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8292#endif
8293#ifdef _PC_XATTR_ENABLED
8294 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8295#endif
8296#ifdef _PC_XATTR_EXISTS
8297 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8298#endif
8299#ifdef _PC_TIMESTAMP_RESOLUTION
8300 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8301#endif
Fred Drakec9680921999-12-13 16:37:25 +00008302};
8303
Fred Drakec9680921999-12-13 16:37:25 +00008304static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008305conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008306{
8307 return conv_confname(arg, valuep, posix_constants_pathconf,
8308 sizeof(posix_constants_pathconf)
8309 / sizeof(struct constdef));
8310}
8311#endif
8312
8313#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008314PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008315"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008316Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008317If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008318
8319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008320posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008321{
8322 PyObject *result = NULL;
8323 int name, fd;
8324
Fred Drake12c6e2d1999-12-14 21:25:03 +00008325 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8326 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008327 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008328
Stefan Krah0e803b32010-11-26 16:16:47 +00008329 errno = 0;
8330 limit = fpathconf(fd, name);
8331 if (limit == -1 && errno != 0)
8332 posix_error();
8333 else
8334 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008335 }
8336 return result;
8337}
8338#endif
8339
8340
8341#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008342PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008343"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008344Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008345If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008346
8347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008348posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008349{
8350 PyObject *result = NULL;
8351 int name;
8352 char *path;
8353
8354 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8355 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008356 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008357
Victor Stinner8c62be82010-05-06 00:08:46 +00008358 errno = 0;
8359 limit = pathconf(path, name);
8360 if (limit == -1 && errno != 0) {
8361 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008362 /* could be a path or name problem */
8363 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008364 else
Stefan Krah99439262010-11-26 12:58:05 +00008365 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008366 }
8367 else
8368 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008369 }
8370 return result;
8371}
8372#endif
8373
8374#ifdef HAVE_CONFSTR
8375static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008376#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008377 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008378#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008379#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008381#endif
8382#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008383 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008384#endif
Fred Draked86ed291999-12-15 15:34:33 +00008385#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008386 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008387#endif
8388#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008389 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008390#endif
8391#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008393#endif
8394#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008395 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008396#endif
Fred Drakec9680921999-12-13 16:37:25 +00008397#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008398 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008399#endif
8400#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008401 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008402#endif
8403#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008404 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008405#endif
8406#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008408#endif
8409#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008411#endif
8412#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008413 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008414#endif
8415#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008416 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008417#endif
8418#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008420#endif
Fred Draked86ed291999-12-15 15:34:33 +00008421#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008423#endif
Fred Drakec9680921999-12-13 16:37:25 +00008424#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008425 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008426#endif
Fred Draked86ed291999-12-15 15:34:33 +00008427#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008429#endif
8430#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008431 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008432#endif
8433#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008435#endif
8436#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008438#endif
Fred Drakec9680921999-12-13 16:37:25 +00008439#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008441#endif
8442#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008444#endif
8445#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008446 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008447#endif
8448#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008450#endif
8451#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008452 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008453#endif
8454#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008456#endif
8457#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008458 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008459#endif
8460#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008461 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008462#endif
8463#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008465#endif
8466#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008467 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008468#endif
8469#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008470 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008471#endif
8472#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008474#endif
8475#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008476 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008477#endif
8478#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008479 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008480#endif
8481#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008483#endif
8484#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008485 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008486#endif
Fred Draked86ed291999-12-15 15:34:33 +00008487#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008488 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008489#endif
8490#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008491 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008492#endif
8493#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008494 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008495#endif
8496#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008497 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008498#endif
8499#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008500 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008501#endif
8502#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008503 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008504#endif
8505#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008506 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008507#endif
8508#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008509 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008510#endif
8511#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008512 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008513#endif
8514#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008515 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008516#endif
8517#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008519#endif
8520#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008521 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008522#endif
8523#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008524 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008525#endif
Fred Drakec9680921999-12-13 16:37:25 +00008526};
8527
8528static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008529conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008530{
8531 return conv_confname(arg, valuep, posix_constants_confstr,
8532 sizeof(posix_constants_confstr)
8533 / sizeof(struct constdef));
8534}
8535
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008536PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008537"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008538Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008539
8540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008541posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008542{
8543 PyObject *result = NULL;
8544 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008545 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008546 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008547
Victor Stinnercb043522010-09-10 23:49:04 +00008548 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8549 return NULL;
8550
8551 errno = 0;
8552 len = confstr(name, buffer, sizeof(buffer));
8553 if (len == 0) {
8554 if (errno) {
8555 posix_error();
8556 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008557 }
8558 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008559 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008560 }
8561 }
Victor Stinnercb043522010-09-10 23:49:04 +00008562
8563 if ((unsigned int)len >= sizeof(buffer)) {
8564 char *buf = PyMem_Malloc(len);
8565 if (buf == NULL)
8566 return PyErr_NoMemory();
8567 confstr(name, buf, len);
8568 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8569 PyMem_Free(buf);
8570 }
8571 else
8572 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008573 return result;
8574}
8575#endif
8576
8577
8578#ifdef HAVE_SYSCONF
8579static struct constdef posix_constants_sysconf[] = {
8580#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008581 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008582#endif
8583#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008584 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008585#endif
8586#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008587 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008588#endif
8589#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008590 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008591#endif
8592#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008593 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008594#endif
8595#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008596 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008597#endif
8598#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008599 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008600#endif
8601#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008602 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008603#endif
8604#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008605 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008606#endif
8607#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008608 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008609#endif
Fred Draked86ed291999-12-15 15:34:33 +00008610#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008611 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008612#endif
8613#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008614 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008615#endif
Fred Drakec9680921999-12-13 16:37:25 +00008616#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008617 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008618#endif
Fred Drakec9680921999-12-13 16:37:25 +00008619#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008620 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008621#endif
8622#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008623 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008624#endif
8625#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008626 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008627#endif
8628#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008629 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008630#endif
8631#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008632 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008633#endif
Fred Draked86ed291999-12-15 15:34:33 +00008634#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008636#endif
Fred Drakec9680921999-12-13 16:37:25 +00008637#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008638 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008639#endif
8640#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008641 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008642#endif
8643#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008644 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008645#endif
8646#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008647 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008648#endif
8649#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008650 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008651#endif
Fred Draked86ed291999-12-15 15:34:33 +00008652#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008653 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008654#endif
Fred Drakec9680921999-12-13 16:37:25 +00008655#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008656 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008657#endif
8658#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008659 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008660#endif
8661#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008662 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008663#endif
8664#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008665 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008666#endif
8667#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008668 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008669#endif
8670#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008671 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008672#endif
8673#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008674 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008675#endif
8676#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008677 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008678#endif
8679#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008680 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008681#endif
8682#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008683 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008684#endif
8685#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008686 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008687#endif
8688#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008689 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008690#endif
8691#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008692 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008693#endif
8694#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008695 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008696#endif
8697#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008698 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008699#endif
8700#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008701 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008702#endif
8703#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008704 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008705#endif
8706#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008707 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008708#endif
8709#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008711#endif
8712#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008713 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008714#endif
8715#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008716 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008717#endif
8718#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008719 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008720#endif
8721#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008722 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008723#endif
Fred Draked86ed291999-12-15 15:34:33 +00008724#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008725 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008726#endif
Fred Drakec9680921999-12-13 16:37:25 +00008727#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008728 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008729#endif
8730#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008732#endif
8733#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008734 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008735#endif
Fred Draked86ed291999-12-15 15:34:33 +00008736#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008738#endif
Fred Drakec9680921999-12-13 16:37:25 +00008739#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008740 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008741#endif
Fred Draked86ed291999-12-15 15:34:33 +00008742#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008744#endif
8745#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008746 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008747#endif
Fred Drakec9680921999-12-13 16:37:25 +00008748#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008749 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008750#endif
8751#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008753#endif
8754#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008755 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008756#endif
8757#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008758 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008759#endif
Fred Draked86ed291999-12-15 15:34:33 +00008760#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008762#endif
Fred Drakec9680921999-12-13 16:37:25 +00008763#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008764 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008765#endif
8766#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008768#endif
8769#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008770 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008771#endif
8772#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008773 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008774#endif
8775#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008776 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008777#endif
8778#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008779 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008780#endif
8781#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008782 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008783#endif
Fred Draked86ed291999-12-15 15:34:33 +00008784#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008785 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008786#endif
Fred Drakec9680921999-12-13 16:37:25 +00008787#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008788 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008789#endif
8790#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008791 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008792#endif
Fred Draked86ed291999-12-15 15:34:33 +00008793#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008794 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008795#endif
Fred Drakec9680921999-12-13 16:37:25 +00008796#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008797 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008798#endif
8799#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008800 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008801#endif
8802#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008803 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008804#endif
8805#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008806 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008807#endif
8808#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008809 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008810#endif
8811#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008812 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008813#endif
8814#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008815 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008816#endif
8817#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008818 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008819#endif
8820#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008822#endif
Fred Draked86ed291999-12-15 15:34:33 +00008823#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008824 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008825#endif
8826#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008827 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008828#endif
Fred Drakec9680921999-12-13 16:37:25 +00008829#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008830 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008831#endif
8832#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008833 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008834#endif
8835#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008836 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008837#endif
8838#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008840#endif
8841#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008843#endif
8844#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008845 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008846#endif
8847#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008848 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008849#endif
8850#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008851 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008852#endif
8853#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008854 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008855#endif
8856#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008857 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008858#endif
8859#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008861#endif
8862#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008863 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008864#endif
8865#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008866 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008867#endif
8868#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008869 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008870#endif
8871#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008872 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008873#endif
8874#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008875 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008876#endif
8877#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008878 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008879#endif
8880#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008881 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008882#endif
8883#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008885#endif
8886#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008887 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008888#endif
8889#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008891#endif
8892#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008894#endif
8895#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008897#endif
8898#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008899 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008900#endif
8901#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008902 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008903#endif
8904#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008905 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008906#endif
8907#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008908 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008909#endif
8910#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008911 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008912#endif
8913#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008914 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008915#endif
8916#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008918#endif
8919#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008920 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008921#endif
8922#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008924#endif
8925#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008926 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008927#endif
8928#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008930#endif
8931#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008932 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008933#endif
Fred Draked86ed291999-12-15 15:34:33 +00008934#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008936#endif
Fred Drakec9680921999-12-13 16:37:25 +00008937#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008939#endif
8940#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008941 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008942#endif
8943#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00008944 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008945#endif
8946#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008947 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008948#endif
8949#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008950 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008951#endif
8952#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00008953 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008954#endif
8955#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00008956 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008957#endif
8958#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008959 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008960#endif
8961#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008963#endif
8964#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008966#endif
8967#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008968 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008969#endif
8970#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008971 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008972#endif
8973#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008974 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008975#endif
8976#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00008977 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008978#endif
8979#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00008980 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008981#endif
8982#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008983 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008984#endif
8985#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008986 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008987#endif
8988#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008989 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008990#endif
8991#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008993#endif
8994#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008996#endif
8997#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008999#endif
9000#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009002#endif
9003#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009005#endif
9006#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009007 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009008#endif
9009#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009011#endif
9012#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009014#endif
9015#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009016 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009017#endif
9018#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009019 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009020#endif
9021#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009022 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009023#endif
9024#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009025 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009026#endif
9027#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009029#endif
9030#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009031 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009032#endif
9033#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009035#endif
9036#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009038#endif
9039#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009041#endif
9042#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009044#endif
9045#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009047#endif
9048#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009049 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009050#endif
9051#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009052 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009053#endif
9054#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009056#endif
9057#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009058 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009059#endif
9060#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009061 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009062#endif
9063#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009065#endif
9066#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009067 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009068#endif
9069#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009070 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009071#endif
9072};
9073
9074static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009075conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009076{
9077 return conv_confname(arg, valuep, posix_constants_sysconf,
9078 sizeof(posix_constants_sysconf)
9079 / sizeof(struct constdef));
9080}
9081
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009082PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009083"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009084Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009085
9086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009087posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009088{
9089 PyObject *result = NULL;
9090 int name;
9091
9092 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9093 int value;
9094
9095 errno = 0;
9096 value = sysconf(name);
9097 if (value == -1 && errno != 0)
9098 posix_error();
9099 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009100 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009101 }
9102 return result;
9103}
9104#endif
9105
9106
Fred Drakebec628d1999-12-15 18:31:10 +00009107/* This code is used to ensure that the tables of configuration value names
9108 * are in sorted order as required by conv_confname(), and also to build the
9109 * the exported dictionaries that are used to publish information about the
9110 * names available on the host platform.
9111 *
9112 * Sorting the table at runtime ensures that the table is properly ordered
9113 * when used, even for platforms we're not able to test on. It also makes
9114 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009115 */
Fred Drakebec628d1999-12-15 18:31:10 +00009116
9117static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009118cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009119{
9120 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009122 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009124
9125 return strcmp(c1->name, c2->name);
9126}
9127
9128static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009129setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009130 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009131{
Fred Drakebec628d1999-12-15 18:31:10 +00009132 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009133 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009134
9135 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9136 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009137 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009139
Barry Warsaw3155db32000-04-13 15:20:40 +00009140 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 PyObject *o = PyLong_FromLong(table[i].value);
9142 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9143 Py_XDECREF(o);
9144 Py_DECREF(d);
9145 return -1;
9146 }
9147 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009148 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009149 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009150}
9151
Fred Drakebec628d1999-12-15 18:31:10 +00009152/* Return -1 on failure, 0 on success. */
9153static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009154setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009155{
9156#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009157 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009158 sizeof(posix_constants_pathconf)
9159 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009160 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009161 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009162#endif
9163#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009164 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009165 sizeof(posix_constants_confstr)
9166 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009167 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009168 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009169#endif
9170#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009171 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009172 sizeof(posix_constants_sysconf)
9173 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009174 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009175 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009176#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009177 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009178}
Fred Draked86ed291999-12-15 15:34:33 +00009179
9180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009181PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009182"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009183Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009184in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009185
9186static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009187posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009188{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009189 abort();
9190 /*NOTREACHED*/
9191 Py_FatalError("abort() called from Python code didn't abort!");
9192 return NULL;
9193}
Fred Drakebec628d1999-12-15 18:31:10 +00009194
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009195#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009196PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009197"startfile(filepath [, operation]) - Start a file with its associated\n\
9198application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009199\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009200When \"operation\" is not specified or \"open\", this acts like\n\
9201double-clicking the file in Explorer, or giving the file name as an\n\
9202argument to the DOS \"start\" command: the file is opened with whatever\n\
9203application (if any) its extension is associated.\n\
9204When another \"operation\" is given, it specifies what should be done with\n\
9205the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009206\n\
9207startfile returns as soon as the associated application is launched.\n\
9208There is no option to wait for the application to close, and no way\n\
9209to retrieve the application's exit status.\n\
9210\n\
9211The filepath is relative to the current directory. If you want to use\n\
9212an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009213the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009214
9215static PyObject *
9216win32_startfile(PyObject *self, PyObject *args)
9217{
Victor Stinner8c62be82010-05-06 00:08:46 +00009218 PyObject *ofilepath;
9219 char *filepath;
9220 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009221 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009222 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009223
Victor Stinnereb5657a2011-09-30 01:44:27 +02009224 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009225 if (!PyArg_ParseTuple(args, "U|s:startfile",
9226 &unipath, &operation)) {
9227 PyErr_Clear();
9228 goto normal;
9229 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009230
Victor Stinner8c62be82010-05-06 00:08:46 +00009231 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009232 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009233 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009234 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009235 PyErr_Clear();
9236 operation = NULL;
9237 goto normal;
9238 }
9239 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009240
Victor Stinnereb5657a2011-09-30 01:44:27 +02009241 wpath = PyUnicode_AsUnicode(unipath);
9242 if (wpath == NULL)
9243 goto normal;
9244 if (uoperation) {
9245 woperation = PyUnicode_AsUnicode(uoperation);
9246 if (woperation == NULL)
9247 goto normal;
9248 }
9249 else
9250 woperation = NULL;
9251
Victor Stinner8c62be82010-05-06 00:08:46 +00009252 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009253 rc = ShellExecuteW((HWND)0, woperation, wpath,
9254 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009255 Py_END_ALLOW_THREADS
9256
Victor Stinnereb5657a2011-09-30 01:44:27 +02009257 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009258 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009259 win32_error_object("startfile", unipath);
9260 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009261 }
9262 Py_INCREF(Py_None);
9263 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009264
9265normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009266 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9267 PyUnicode_FSConverter, &ofilepath,
9268 &operation))
9269 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009270 if (win32_warn_bytes_api()) {
9271 Py_DECREF(ofilepath);
9272 return NULL;
9273 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009274 filepath = PyBytes_AsString(ofilepath);
9275 Py_BEGIN_ALLOW_THREADS
9276 rc = ShellExecute((HWND)0, operation, filepath,
9277 NULL, NULL, SW_SHOWNORMAL);
9278 Py_END_ALLOW_THREADS
9279 if (rc <= (HINSTANCE)32) {
9280 PyObject *errval = win32_error("startfile", filepath);
9281 Py_DECREF(ofilepath);
9282 return errval;
9283 }
9284 Py_DECREF(ofilepath);
9285 Py_INCREF(Py_None);
9286 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009287}
9288#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009289
Martin v. Löwis438b5342002-12-27 10:16:42 +00009290#ifdef HAVE_GETLOADAVG
9291PyDoc_STRVAR(posix_getloadavg__doc__,
9292"getloadavg() -> (float, float, float)\n\n\
9293Return the number of processes in the system run queue averaged over\n\
9294the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9295was unobtainable");
9296
9297static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009298posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009299{
9300 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009301 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009302 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9303 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009304 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009305 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009306}
9307#endif
9308
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009309#ifdef MS_WINDOWS
9310
9311PyDoc_STRVAR(win32_urandom__doc__,
9312"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009313Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009314
9315typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
9316 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
9317 DWORD dwFlags );
9318typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
9319 BYTE *pbBuffer );
9320
9321static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00009322/* This handle is never explicitly released. Instead, the operating
9323 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009324static HCRYPTPROV hCryptProv = 0;
9325
Tim Peters4ad82172004-08-30 17:02:04 +00009326static PyObject*
9327win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009328{
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 int howMany;
9330 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009331
Victor Stinner8c62be82010-05-06 00:08:46 +00009332 /* Read arguments */
9333 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9334 return NULL;
9335 if (howMany < 0)
9336 return PyErr_Format(PyExc_ValueError,
9337 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009338
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 if (hCryptProv == 0) {
9340 HINSTANCE hAdvAPI32 = NULL;
9341 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009342
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 /* Obtain handle to the DLL containing CryptoAPI
9344 This should not fail */
Martin v. Löwis50590f12012-01-14 17:54:09 +01009345 hAdvAPI32 = GetModuleHandleW(L"advapi32.dll");
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 if(hAdvAPI32 == NULL)
9347 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009348
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 /* Obtain pointers to the CryptoAPI functions
9350 This will fail on some early versions of Win95 */
9351 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
9352 hAdvAPI32,
9353 "CryptAcquireContextA");
9354 if (pCryptAcquireContext == NULL)
9355 return PyErr_Format(PyExc_NotImplementedError,
9356 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009357
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
9359 hAdvAPI32, "CryptGenRandom");
9360 if (pCryptGenRandom == NULL)
9361 return PyErr_Format(PyExc_NotImplementedError,
9362 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009363
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 /* Acquire context */
9365 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
9366 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
9367 return win32_error("CryptAcquireContext", NULL);
9368 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009369
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 /* Allocate bytes */
9371 result = PyBytes_FromStringAndSize(NULL, howMany);
9372 if (result != NULL) {
9373 /* Get random data */
9374 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
9375 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
9376 PyBytes_AS_STRING(result))) {
9377 Py_DECREF(result);
9378 return win32_error("CryptGenRandom", NULL);
9379 }
9380 }
9381 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009382}
9383#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009384
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009385PyDoc_STRVAR(device_encoding__doc__,
9386"device_encoding(fd) -> str\n\n\
9387Return a string describing the encoding of the device\n\
9388if the output is a terminal; else return None.");
9389
9390static PyObject *
9391device_encoding(PyObject *self, PyObject *args)
9392{
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 int fd;
Victor Stinner7870bdf2011-05-23 18:12:52 +02009394#if defined(MS_WINDOWS) || defined(MS_WIN64)
9395 UINT cp;
9396#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9398 return NULL;
9399 if (!_PyVerify_fd(fd) || !isatty(fd)) {
9400 Py_INCREF(Py_None);
9401 return Py_None;
9402 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009403#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner7870bdf2011-05-23 18:12:52 +02009404 if (fd == 0)
9405 cp = GetConsoleCP();
9406 else if (fd == 1 || fd == 2)
9407 cp = GetConsoleOutputCP();
9408 else
9409 cp = 0;
9410 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
9411 has no console */
9412 if (cp != 0)
9413 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009414#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00009415 {
9416 char *codeset = nl_langinfo(CODESET);
9417 if (codeset != NULL && codeset[0] != 0)
9418 return PyUnicode_FromString(codeset);
9419 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009420#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 Py_INCREF(Py_None);
9422 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009423}
9424
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009425#ifdef __VMS
9426/* Use openssl random routine */
9427#include <openssl/rand.h>
9428PyDoc_STRVAR(vms_urandom__doc__,
9429"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009430Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009431
9432static PyObject*
9433vms_urandom(PyObject *self, PyObject *args)
9434{
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 int howMany;
9436 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009437
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 /* Read arguments */
9439 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9440 return NULL;
9441 if (howMany < 0)
9442 return PyErr_Format(PyExc_ValueError,
9443 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009444
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 /* Allocate bytes */
9446 result = PyBytes_FromStringAndSize(NULL, howMany);
9447 if (result != NULL) {
9448 /* Get random data */
9449 if (RAND_pseudo_bytes((unsigned char*)
9450 PyBytes_AS_STRING(result),
9451 howMany) < 0) {
9452 Py_DECREF(result);
9453 return PyErr_Format(PyExc_ValueError,
9454 "RAND_pseudo_bytes");
9455 }
9456 }
9457 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009458}
9459#endif
9460
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009461#ifdef HAVE_SETRESUID
9462PyDoc_STRVAR(posix_setresuid__doc__,
9463"setresuid(ruid, euid, suid)\n\n\
9464Set the current process's real, effective, and saved user ids.");
9465
9466static PyObject*
9467posix_setresuid (PyObject *self, PyObject *args)
9468{
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 /* We assume uid_t is no larger than a long. */
9470 long ruid, euid, suid;
9471 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9472 return NULL;
9473 if (setresuid(ruid, euid, suid) < 0)
9474 return posix_error();
9475 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009476}
9477#endif
9478
9479#ifdef HAVE_SETRESGID
9480PyDoc_STRVAR(posix_setresgid__doc__,
9481"setresgid(rgid, egid, sgid)\n\n\
9482Set the current process's real, effective, and saved group ids.");
9483
9484static PyObject*
9485posix_setresgid (PyObject *self, PyObject *args)
9486{
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 /* We assume uid_t is no larger than a long. */
9488 long rgid, egid, sgid;
9489 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9490 return NULL;
9491 if (setresgid(rgid, egid, sgid) < 0)
9492 return posix_error();
9493 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009494}
9495#endif
9496
9497#ifdef HAVE_GETRESUID
9498PyDoc_STRVAR(posix_getresuid__doc__,
9499"getresuid() -> (ruid, euid, suid)\n\n\
9500Get tuple of the current process's real, effective, and saved user ids.");
9501
9502static PyObject*
9503posix_getresuid (PyObject *self, PyObject *noargs)
9504{
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 uid_t ruid, euid, suid;
9506 long l_ruid, l_euid, l_suid;
9507 if (getresuid(&ruid, &euid, &suid) < 0)
9508 return posix_error();
9509 /* Force the values into long's as we don't know the size of uid_t. */
9510 l_ruid = ruid;
9511 l_euid = euid;
9512 l_suid = suid;
9513 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009514}
9515#endif
9516
9517#ifdef HAVE_GETRESGID
9518PyDoc_STRVAR(posix_getresgid__doc__,
9519"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009520Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009521
9522static PyObject*
9523posix_getresgid (PyObject *self, PyObject *noargs)
9524{
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 uid_t rgid, egid, sgid;
9526 long l_rgid, l_egid, l_sgid;
9527 if (getresgid(&rgid, &egid, &sgid) < 0)
9528 return posix_error();
9529 /* Force the values into long's as we don't know the size of uid_t. */
9530 l_rgid = rgid;
9531 l_egid = egid;
9532 l_sgid = sgid;
9533 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009534}
9535#endif
9536
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009537/* Posix *at family of functions:
9538 faccessat, fchmodat, fchownat, fstatat, futimesat,
9539 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9540 unlinkat, utimensat, mkfifoat */
9541
9542#ifdef HAVE_FACCESSAT
9543PyDoc_STRVAR(posix_faccessat__doc__,
9544"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9545Like access() but if path is relative, it is taken as relative to dirfd.\n\
9546flags is optional and can be constructed by ORing together zero or more\n\
9547of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
9548If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9549is interpreted relative to the current working directory.");
9550
9551static PyObject *
9552posix_faccessat(PyObject *self, PyObject *args)
9553{
9554 PyObject *opath;
9555 char *path;
9556 int mode;
9557 int res;
9558 int dirfd, flags = 0;
9559 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9560 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9561 return NULL;
9562 path = PyBytes_AsString(opath);
9563 Py_BEGIN_ALLOW_THREADS
9564 res = faccessat(dirfd, path, mode, flags);
9565 Py_END_ALLOW_THREADS
9566 Py_DECREF(opath);
9567 return PyBool_FromLong(res == 0);
9568}
9569#endif
9570
9571#ifdef HAVE_FCHMODAT
9572PyDoc_STRVAR(posix_fchmodat__doc__,
9573"fchmodat(dirfd, path, mode, flags=0)\n\n\
9574Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9575flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9576If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9577is interpreted relative to the current working directory.");
9578
9579static PyObject *
9580posix_fchmodat(PyObject *self, PyObject *args)
9581{
9582 int dirfd, mode, res;
9583 int flags = 0;
9584 PyObject *opath;
9585 char *path;
9586
9587 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9588 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9589 return NULL;
9590
9591 path = PyBytes_AsString(opath);
9592
9593 Py_BEGIN_ALLOW_THREADS
9594 res = fchmodat(dirfd, path, mode, flags);
9595 Py_END_ALLOW_THREADS
9596 Py_DECREF(opath);
9597 if (res < 0)
9598 return posix_error();
9599 Py_RETURN_NONE;
9600}
9601#endif /* HAVE_FCHMODAT */
9602
9603#ifdef HAVE_FCHOWNAT
9604PyDoc_STRVAR(posix_fchownat__doc__,
9605"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9606Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9607flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9608If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9609is interpreted relative to the current working directory.");
9610
9611static PyObject *
9612posix_fchownat(PyObject *self, PyObject *args)
9613{
9614 PyObject *opath;
9615 int dirfd, res;
9616 long uid, gid;
9617 int flags = 0;
9618 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009619
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009620 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9621 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9622 return NULL;
9623
9624 path = PyBytes_AsString(opath);
9625
9626 Py_BEGIN_ALLOW_THREADS
9627 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9628 Py_END_ALLOW_THREADS
9629 Py_DECREF(opath);
9630 if (res < 0)
9631 return posix_error();
9632 Py_RETURN_NONE;
9633}
9634#endif /* HAVE_FCHOWNAT */
9635
9636#ifdef HAVE_FSTATAT
9637PyDoc_STRVAR(posix_fstatat__doc__,
9638"fstatat(dirfd, path, flags=0) -> stat result\n\n\
9639Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9640flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9641If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9642is interpreted relative to the current working directory.");
9643
9644static PyObject *
9645posix_fstatat(PyObject *self, PyObject *args)
9646{
9647 PyObject *opath;
9648 char *path;
9649 STRUCT_STAT st;
9650 int dirfd, res, flags = 0;
9651
9652 if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
9653 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9654 return NULL;
9655 path = PyBytes_AsString(opath);
9656
9657 Py_BEGIN_ALLOW_THREADS
9658 res = fstatat(dirfd, path, &st, flags);
9659 Py_END_ALLOW_THREADS
9660 Py_DECREF(opath);
9661 if (res != 0)
9662 return posix_error();
9663
9664 return _pystat_fromstructstat(&st);
9665}
9666#endif
9667
9668#ifdef HAVE_FUTIMESAT
9669PyDoc_STRVAR(posix_futimesat__doc__,
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009670"futimesat(dirfd, path[, (atime, mtime)])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009671Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9672If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9673is interpreted relative to the current working directory.");
9674
9675static PyObject *
9676posix_futimesat(PyObject *self, PyObject *args)
9677{
9678 PyObject *opath;
9679 char *path;
9680 int res, dirfd;
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009681 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009682 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009683 long ansec, mnsec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009684
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009685 if (!PyArg_ParseTuple(args, "iO&|O:futimesat",
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009686 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9687 return NULL;
9688 path = PyBytes_AsString(opath);
9689 if (arg == Py_None) {
9690 /* optional time values not given */
9691 Py_BEGIN_ALLOW_THREADS
9692 res = futimesat(dirfd, path, NULL);
9693 Py_END_ALLOW_THREADS
9694 }
9695 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9696 PyErr_SetString(PyExc_TypeError,
9697 "futimesat() arg 3 must be a tuple (atime, mtime)");
9698 Py_DECREF(opath);
9699 return NULL;
9700 }
9701 else {
9702 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01009703 &atime, &ansec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009704 Py_DECREF(opath);
9705 return NULL;
9706 }
9707 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01009708 &mtime, &mnsec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009709 Py_DECREF(opath);
9710 return NULL;
9711 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009712
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009713 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009714 {
9715#ifdef HAVE_UTIMENSAT
9716 struct timespec buf[2];
9717 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009718 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009719 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009720 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009721 res = utimensat(dirfd, path, buf, 0);
9722#else
9723 struct timeval buf[2];
9724 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009725 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009726 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009727 buf[1].tv_usec = mnsec / 1000;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009728 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009729#endif
9730 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009731 Py_END_ALLOW_THREADS
9732 }
9733 Py_DECREF(opath);
9734 if (res < 0) {
9735 return posix_error();
9736 }
9737 Py_RETURN_NONE;
9738}
9739#endif
9740
9741#ifdef HAVE_LINKAT
9742PyDoc_STRVAR(posix_linkat__doc__,
9743"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9744Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9745and if dstpath is relative, it is taken as relative to dstfd.\n\
9746flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9747If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9748srcpath is interpreted relative to the current working directory. This\n\
9749also applies for dstpath.");
9750
9751static PyObject *
9752posix_linkat(PyObject *self, PyObject *args)
9753{
9754 PyObject *osrc, *odst;
9755 char *src, *dst;
9756 int res, srcfd, dstfd;
9757 int flags = 0;
9758
9759 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9760 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9761 return NULL;
9762 src = PyBytes_AsString(osrc);
9763 dst = PyBytes_AsString(odst);
9764 Py_BEGIN_ALLOW_THREADS
9765 res = linkat(srcfd, src, dstfd, dst, flags);
9766 Py_END_ALLOW_THREADS
9767 Py_DECREF(osrc);
9768 Py_DECREF(odst);
9769 if (res < 0)
9770 return posix_error();
9771 Py_RETURN_NONE;
9772}
9773#endif /* HAVE_LINKAT */
9774
9775#ifdef HAVE_MKDIRAT
9776PyDoc_STRVAR(posix_mkdirat__doc__,
9777"mkdirat(dirfd, path, mode=0o777)\n\n\
9778Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9779If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9780is interpreted relative to the current working directory.");
9781
9782static PyObject *
9783posix_mkdirat(PyObject *self, PyObject *args)
9784{
9785 int res, dirfd;
9786 PyObject *opath;
9787 char *path;
9788 int mode = 0777;
9789
9790 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9791 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9792 return NULL;
9793 path = PyBytes_AsString(opath);
9794 Py_BEGIN_ALLOW_THREADS
9795 res = mkdirat(dirfd, path, mode);
9796 Py_END_ALLOW_THREADS
9797 Py_DECREF(opath);
9798 if (res < 0)
9799 return posix_error();
9800 Py_RETURN_NONE;
9801}
9802#endif
9803
9804#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9805PyDoc_STRVAR(posix_mknodat__doc__,
9806"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9807Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9808If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9809is interpreted relative to the current working directory.");
9810
9811static PyObject *
9812posix_mknodat(PyObject *self, PyObject *args)
9813{
9814 PyObject *opath;
9815 char *filename;
9816 int mode = 0600;
9817 int device = 0;
9818 int res, dirfd;
9819 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9820 PyUnicode_FSConverter, &opath, &mode, &device))
9821 return NULL;
9822 filename = PyBytes_AS_STRING(opath);
9823 Py_BEGIN_ALLOW_THREADS
9824 res = mknodat(dirfd, filename, mode, device);
9825 Py_END_ALLOW_THREADS
9826 Py_DECREF(opath);
9827 if (res < 0)
9828 return posix_error();
9829 Py_RETURN_NONE;
9830}
9831#endif
9832
9833#ifdef HAVE_OPENAT
9834PyDoc_STRVAR(posix_openat__doc__,
9835"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9836Like open() but if path is relative, it is taken as relative to dirfd.\n\
9837If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9838is interpreted relative to the current working directory.");
9839
9840static PyObject *
9841posix_openat(PyObject *self, PyObject *args)
9842{
9843 PyObject *ofile;
9844 char *file;
9845 int flag, dirfd, fd;
9846 int mode = 0777;
9847
9848 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9849 &dirfd, PyUnicode_FSConverter, &ofile,
9850 &flag, &mode))
9851 return NULL;
9852 file = PyBytes_AsString(ofile);
9853 Py_BEGIN_ALLOW_THREADS
9854 fd = openat(dirfd, file, flag, mode);
9855 Py_END_ALLOW_THREADS
9856 Py_DECREF(ofile);
9857 if (fd < 0)
9858 return posix_error();
9859 return PyLong_FromLong((long)fd);
9860}
9861#endif
9862
9863#ifdef HAVE_READLINKAT
9864PyDoc_STRVAR(posix_readlinkat__doc__,
9865"readlinkat(dirfd, path) -> path\n\n\
9866Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9867If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9868is interpreted relative to the current working directory.");
9869
9870static PyObject *
9871posix_readlinkat(PyObject *self, PyObject *args)
9872{
9873 PyObject *v, *opath;
9874 char buf[MAXPATHLEN];
9875 char *path;
9876 int n, dirfd;
9877 int arg_is_unicode = 0;
9878
9879 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9880 &dirfd, PyUnicode_FSConverter, &opath))
9881 return NULL;
9882 path = PyBytes_AsString(opath);
9883 v = PySequence_GetItem(args, 1);
9884 if (v == NULL) {
9885 Py_DECREF(opath);
9886 return NULL;
9887 }
9888
9889 if (PyUnicode_Check(v)) {
9890 arg_is_unicode = 1;
9891 }
9892 Py_DECREF(v);
9893
9894 Py_BEGIN_ALLOW_THREADS
9895 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9896 Py_END_ALLOW_THREADS
9897 Py_DECREF(opath);
9898 if (n < 0)
9899 return posix_error();
9900
9901 if (arg_is_unicode)
9902 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9903 else
9904 return PyBytes_FromStringAndSize(buf, n);
9905}
9906#endif /* HAVE_READLINKAT */
9907
9908#ifdef HAVE_RENAMEAT
9909PyDoc_STRVAR(posix_renameat__doc__,
9910"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9911Like rename() but if oldpath is relative, it is taken as relative to\n\
9912olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9913If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9914oldpath is interpreted relative to the current working directory. This\n\
9915also applies for newpath.");
9916
9917static PyObject *
9918posix_renameat(PyObject *self, PyObject *args)
9919{
9920 int res;
9921 PyObject *opathold, *opathnew;
9922 char *opath, *npath;
9923 int oldfd, newfd;
9924
9925 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9926 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9927 return NULL;
9928 opath = PyBytes_AsString(opathold);
9929 npath = PyBytes_AsString(opathnew);
9930 Py_BEGIN_ALLOW_THREADS
9931 res = renameat(oldfd, opath, newfd, npath);
9932 Py_END_ALLOW_THREADS
9933 Py_DECREF(opathold);
9934 Py_DECREF(opathnew);
9935 if (res < 0)
9936 return posix_error();
9937 Py_RETURN_NONE;
9938}
9939#endif
9940
9941#if HAVE_SYMLINKAT
9942PyDoc_STRVAR(posix_symlinkat__doc__,
9943"symlinkat(src, dstfd, dst)\n\n\
9944Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
9945If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
9946is interpreted relative to the current working directory.");
9947
9948static PyObject *
9949posix_symlinkat(PyObject *self, PyObject *args)
9950{
9951 int res, dstfd;
9952 PyObject *osrc, *odst;
9953 char *src, *dst;
9954
9955 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
9956 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
9957 return NULL;
9958 src = PyBytes_AsString(osrc);
9959 dst = PyBytes_AsString(odst);
9960 Py_BEGIN_ALLOW_THREADS
9961 res = symlinkat(src, dstfd, dst);
9962 Py_END_ALLOW_THREADS
9963 Py_DECREF(osrc);
9964 Py_DECREF(odst);
9965 if (res < 0)
9966 return posix_error();
9967 Py_RETURN_NONE;
9968}
9969#endif /* HAVE_SYMLINKAT */
9970
9971#ifdef HAVE_UNLINKAT
9972PyDoc_STRVAR(posix_unlinkat__doc__,
9973"unlinkat(dirfd, path, flags=0)\n\n\
9974Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
9975flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
9976specified, unlinkat() behaves like rmdir().\n\
9977If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9978is interpreted relative to the current working directory.");
9979
9980static PyObject *
9981posix_unlinkat(PyObject *self, PyObject *args)
9982{
9983 int dirfd, res, flags = 0;
9984 PyObject *opath;
9985 char *path;
9986
9987 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
9988 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9989 return NULL;
9990 path = PyBytes_AsString(opath);
9991 Py_BEGIN_ALLOW_THREADS
9992 res = unlinkat(dirfd, path, flags);
9993 Py_END_ALLOW_THREADS
9994 Py_DECREF(opath);
9995 if (res < 0)
9996 return posix_error();
9997 Py_RETURN_NONE;
9998}
9999#endif
10000
10001#ifdef HAVE_UTIMENSAT
10002PyDoc_STRVAR(posix_utimensat__doc__,
Brian Curtin569b4942011-11-07 16:09:20 -060010003"utimensat(dirfd, path[, atime=(atime_sec, atime_nsec),\n\
10004 mtime=(mtime_sec, mtime_nsec), flags=0])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010005utimensat(dirfd, path, None, None, flags)\n\n\
10006Updates the timestamps of a file with nanosecond precision. If path is\n\
10007relative, it is taken as relative to dirfd.\n\
Brian Curtin569b4942011-11-07 16:09:20 -060010008If atime and mtime are both None, which is the default, set atime and\n\
10009mtime to the current time.\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010010flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
10011If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10012is interpreted relative to the current working directory.\n\
10013If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
10014current time.\n\
10015If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
10016
10017static PyObject *
Brian Curtin569b4942011-11-07 16:09:20 -060010018posix_utimensat(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010019{
10020 PyObject *opath;
10021 char *path;
10022 int res, dirfd, flags = 0;
Brian Curtin569b4942011-11-07 16:09:20 -060010023 PyObject *atime = Py_None;
10024 PyObject *mtime = Py_None;
10025
10026 static char *kwlist[] = {"dirfd", "path", "atime", "mtime", "flags", NULL};
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010027
10028 struct timespec buf[2];
10029
Brian Curtin569b4942011-11-07 16:09:20 -060010030 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|OOi:utimensat", kwlist,
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010031 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
10032 return NULL;
10033 path = PyBytes_AsString(opath);
10034 if (atime == Py_None && mtime == Py_None) {
10035 /* optional time values not given */
10036 Py_BEGIN_ALLOW_THREADS
10037 res = utimensat(dirfd, path, NULL, flags);
10038 Py_END_ALLOW_THREADS
10039 }
10040 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
10041 PyErr_SetString(PyExc_TypeError,
10042 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
10043 Py_DECREF(opath);
10044 return NULL;
10045 }
10046 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
10047 PyErr_SetString(PyExc_TypeError,
10048 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
10049 Py_DECREF(opath);
10050 return NULL;
10051 }
10052 else {
10053 if (!PyArg_ParseTuple(atime, "ll:utimensat",
10054 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
10055 Py_DECREF(opath);
10056 return NULL;
10057 }
10058 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
10059 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
10060 Py_DECREF(opath);
10061 return NULL;
10062 }
10063 Py_BEGIN_ALLOW_THREADS
10064 res = utimensat(dirfd, path, buf, flags);
10065 Py_END_ALLOW_THREADS
10066 }
10067 Py_DECREF(opath);
10068 if (res < 0) {
10069 return posix_error();
10070 }
10071 Py_RETURN_NONE;
10072}
10073#endif
10074
10075#ifdef HAVE_MKFIFOAT
10076PyDoc_STRVAR(posix_mkfifoat__doc__,
10077"mkfifoat(dirfd, path, mode=0o666)\n\n\
10078Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
10079If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10080is interpreted relative to the current working directory.");
10081
10082static PyObject *
10083posix_mkfifoat(PyObject *self, PyObject *args)
10084{
10085 PyObject *opath;
10086 char *filename;
10087 int mode = 0666;
10088 int res, dirfd;
10089 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
10090 &dirfd, PyUnicode_FSConverter, &opath, &mode))
10091 return NULL;
10092 filename = PyBytes_AS_STRING(opath);
10093 Py_BEGIN_ALLOW_THREADS
10094 res = mkfifoat(dirfd, filename, mode);
10095 Py_END_ALLOW_THREADS
10096 Py_DECREF(opath);
10097 if (res < 0)
10098 return posix_error();
10099 Py_RETURN_NONE;
10100}
10101#endif
10102
Benjamin Peterson9428d532011-09-14 11:45:52 -040010103#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010104
10105static int
10106try_getxattr(const char *path, const char *name,
10107 ssize_t (*get)(const char *, const char *, void *, size_t),
10108 Py_ssize_t buf_size, PyObject **res)
10109{
10110 PyObject *value;
10111 Py_ssize_t len;
10112
10113 assert(buf_size <= XATTR_SIZE_MAX);
10114 value = PyBytes_FromStringAndSize(NULL, buf_size);
10115 if (!value)
10116 return 0;
10117 Py_BEGIN_ALLOW_THREADS;
10118 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10119 Py_END_ALLOW_THREADS;
10120 if (len < 0) {
10121 Py_DECREF(value);
10122 if (errno == ERANGE) {
10123 value = NULL;
10124 }
10125 else {
10126 posix_error();
10127 return 0;
10128 }
10129 }
10130 else if (len != buf_size) {
10131 /* Can only shrink. */
10132 _PyBytes_Resize(&value, len);
10133 }
10134 *res = value;
10135 return 1;
10136}
10137
10138static PyObject *
10139getxattr_common(const char *path, PyObject *name_obj,
10140 ssize_t (*get)(const char *, const char *, void *, size_t))
10141{
10142 PyObject *value;
10143 const char *name = PyBytes_AS_STRING(name_obj);
10144
10145 /* Try a small value first. */
10146 if (!try_getxattr(path, name, get, 128, &value))
10147 return NULL;
10148 if (value)
10149 return value;
10150 /* Now the maximum possible one. */
10151 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10152 return NULL;
10153 assert(value);
10154 return value;
10155}
10156
10157PyDoc_STRVAR(posix_getxattr__doc__,
10158"getxattr(path, attr) -> value\n\n\
10159Return the value of extended attribute *name* on *path*.");
10160
10161static PyObject *
10162posix_getxattr(PyObject *self, PyObject *args)
10163{
10164 PyObject *path, *res, *name;
10165
10166 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10167 PyUnicode_FSConverter, &name))
10168 return NULL;
10169 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10170 Py_DECREF(path);
10171 Py_DECREF(name);
10172 return res;
10173}
10174
10175PyDoc_STRVAR(posix_lgetxattr__doc__,
10176"lgetxattr(path, attr) -> value\n\n\
10177Like getxattr but don't follow symlinks.");
10178
10179static PyObject *
10180posix_lgetxattr(PyObject *self, PyObject *args)
10181{
10182 PyObject *path, *res, *name;
10183
10184 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10185 PyUnicode_FSConverter, &name))
10186 return NULL;
10187 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10188 Py_DECREF(path);
10189 Py_DECREF(name);
10190 return res;
10191}
10192
10193static ssize_t
10194wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10195{
10196 /* Hack to share code. */
10197 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10198}
10199
10200PyDoc_STRVAR(posix_fgetxattr__doc__,
10201"fgetxattr(fd, attr) -> value\n\n\
10202Like getxattr but operate on a fd instead of a path.");
10203
10204static PyObject *
10205posix_fgetxattr(PyObject *self, PyObject *args)
10206{
10207 PyObject *res, *name;
10208 int fd;
10209
10210 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10211 return NULL;
10212 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10213 Py_DECREF(name);
10214 return res;
10215}
10216
10217PyDoc_STRVAR(posix_setxattr__doc__,
10218"setxattr(path, attr, value, flags=0)\n\n\
10219Set extended attribute *attr* on *path* to *value*.");
10220
10221static PyObject *
10222posix_setxattr(PyObject *self, PyObject *args)
10223{
10224 PyObject *path, *name;
10225 Py_buffer data;
10226 int flags = 0, err;
10227
10228 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10229 &path, PyUnicode_FSConverter, &name, &data, &flags))
10230 return NULL;
10231 Py_BEGIN_ALLOW_THREADS;
10232 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10233 data.buf, data.len, flags);
10234 Py_END_ALLOW_THREADS;
10235 Py_DECREF(path);
10236 Py_DECREF(name);
10237 PyBuffer_Release(&data);
10238 if (err)
10239 return posix_error();
10240 Py_RETURN_NONE;
10241}
10242
10243PyDoc_STRVAR(posix_lsetxattr__doc__,
10244"lsetxattr(path, attr, value, flags=0)\n\n\
10245Like setxattr but don't follow symlinks.");
10246
10247static PyObject *
10248posix_lsetxattr(PyObject *self, PyObject *args)
10249{
10250 PyObject *path, *name;
10251 Py_buffer data;
10252 int flags = 0, err;
10253
10254 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10255 &path, PyUnicode_FSConverter, &name, &data, &flags))
10256 return NULL;
10257 Py_BEGIN_ALLOW_THREADS;
10258 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10259 data.buf, data.len, flags);
10260 Py_END_ALLOW_THREADS;
10261 Py_DECREF(path);
10262 Py_DECREF(name);
10263 PyBuffer_Release(&data);
10264 if (err)
10265 return posix_error();
10266 Py_RETURN_NONE;
10267}
10268
10269PyDoc_STRVAR(posix_fsetxattr__doc__,
10270"fsetxattr(fd, attr, value, flags=0)\n\n\
10271Like setxattr but operates on *fd* instead of a path.");
10272
10273static PyObject *
10274posix_fsetxattr(PyObject *self, PyObject *args)
10275{
10276 Py_buffer data;
10277 const char *name;
10278 int fd, flags = 0, err;
10279
10280 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10281 &name, &data, &flags))
10282 return NULL;
10283 Py_BEGIN_ALLOW_THREADS;
10284 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10285 Py_END_ALLOW_THREADS;
10286 Py_DECREF(name);
10287 PyBuffer_Release(&data);
10288 if (err)
10289 return posix_error();
10290 Py_RETURN_NONE;
10291}
10292
10293PyDoc_STRVAR(posix_removexattr__doc__,
10294"removexattr(path, attr)\n\n\
10295Remove extended attribute *attr* on *path*.");
10296
10297static PyObject *
10298posix_removexattr(PyObject *self, PyObject *args)
10299{
10300 PyObject *path, *name;
10301 int err;
10302
10303 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10304 PyUnicode_FSConverter, &name))
10305 return NULL;
10306 Py_BEGIN_ALLOW_THREADS;
10307 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10308 Py_END_ALLOW_THREADS;
10309 Py_DECREF(path);
10310 Py_DECREF(name);
10311 if (err)
10312 return posix_error();
10313 Py_RETURN_NONE;
10314}
10315
10316PyDoc_STRVAR(posix_lremovexattr__doc__,
10317"lremovexattr(path, attr)\n\n\
10318Like removexattr but don't follow symlinks.");
10319
10320static PyObject *
10321posix_lremovexattr(PyObject *self, PyObject *args)
10322{
10323 PyObject *path, *name;
10324 int err;
10325
10326 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10327 PyUnicode_FSConverter, &name))
10328 return NULL;
10329 Py_BEGIN_ALLOW_THREADS;
10330 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10331 Py_END_ALLOW_THREADS;
10332 Py_DECREF(path);
10333 Py_DECREF(name);
10334 if (err)
10335 return posix_error();
10336 Py_RETURN_NONE;
10337}
10338
10339PyDoc_STRVAR(posix_fremovexattr__doc__,
10340"fremovexattr(fd, attr)\n\n\
10341Like removexattr but operates on a file descriptor.");
10342
10343static PyObject *
10344posix_fremovexattr(PyObject *self, PyObject *args)
10345{
10346 PyObject *name;
10347 int fd, err;
10348
10349 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10350 PyUnicode_FSConverter, &name))
10351 return NULL;
10352 Py_BEGIN_ALLOW_THREADS;
10353 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10354 Py_END_ALLOW_THREADS;
10355 Py_DECREF(name);
10356 if (err)
10357 return posix_error();
10358 Py_RETURN_NONE;
10359}
10360
10361static Py_ssize_t
10362try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10363 Py_ssize_t buf_size, char **buf)
10364{
10365 Py_ssize_t len;
10366
10367 *buf = PyMem_MALLOC(buf_size);
10368 if (!*buf) {
10369 PyErr_NoMemory();
10370 return -1;
10371 }
10372 Py_BEGIN_ALLOW_THREADS;
10373 len = list(path, *buf, buf_size);
10374 Py_END_ALLOW_THREADS;
10375 if (len < 0) {
10376 PyMem_FREE(*buf);
10377 if (errno != ERANGE)
10378 posix_error();
10379 return -1;
10380 }
10381 return len;
10382}
10383
10384static PyObject *
10385listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10386{
10387 PyObject *res, *attr;
10388 Py_ssize_t len, err, start, i;
10389 char *buf;
10390
10391 len = try_listxattr(path, list, 256, &buf);
10392 if (len < 0) {
10393 if (PyErr_Occurred())
10394 return NULL;
10395 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10396 if (len < 0)
10397 return NULL;
10398 }
10399 res = PyList_New(0);
10400 if (!res) {
10401 PyMem_FREE(buf);
10402 return NULL;
10403 }
10404 for (start = i = 0; i < len; i++) {
10405 if (!buf[i]) {
10406 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10407 if (!attr) {
10408 Py_DECREF(res);
10409 PyMem_FREE(buf);
10410 return NULL;
10411 }
10412 err = PyList_Append(res, attr);
10413 Py_DECREF(attr);
10414 if (err) {
10415 Py_DECREF(res);
10416 PyMem_FREE(buf);
10417 return NULL;
10418 }
10419 start = i + 1;
10420 }
10421 }
10422 PyMem_FREE(buf);
10423 return res;
10424}
10425
10426PyDoc_STRVAR(posix_listxattr__doc__,
10427"listxattr(path)\n\n\
10428Return a list of extended attributes on *path*.");
10429
10430static PyObject *
10431posix_listxattr(PyObject *self, PyObject *args)
10432{
10433 PyObject *path, *res;
10434
10435 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10436 return NULL;
10437 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10438 Py_DECREF(path);
10439 return res;
10440}
10441
10442PyDoc_STRVAR(posix_llistxattr__doc__,
10443"llistxattr(path)\n\n\
10444Like listxattr but don't follow symlinks..");
10445
10446static PyObject *
10447posix_llistxattr(PyObject *self, PyObject *args)
10448{
10449 PyObject *path, *res;
10450
10451 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10452 return NULL;
10453 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10454 Py_DECREF(path);
10455 return res;
10456}
10457
10458static ssize_t
10459wrap_flistxattr(const char *path, char *buf, size_t len)
10460{
10461 /* Hack to share code. */
10462 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10463}
10464
10465PyDoc_STRVAR(posix_flistxattr__doc__,
10466"flistxattr(path)\n\n\
10467Like flistxattr but operates on a file descriptor.");
10468
10469static PyObject *
10470posix_flistxattr(PyObject *self, PyObject *args)
10471{
10472 long fd;
10473
10474 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10475 return NULL;
10476 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10477}
10478
Benjamin Peterson9428d532011-09-14 11:45:52 -040010479#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010480
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010481static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010483#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010485#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010487#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010488 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010489#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010491#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010493#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010494#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010495 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010496#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010497#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010498 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010499#endif /* HAVE_LCHMOD */
10500#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010501 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010502#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010503#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010504 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010505#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010506#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010507 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010508#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010509#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010510 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010511#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010512#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010513 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010514#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010515#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010516 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10517 METH_NOARGS, posix_getcwd__doc__},
10518 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10519 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010520#endif
10521#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010522 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010523#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010524 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010525#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +010010526 {"flistdir", posix_flistdir, METH_VARARGS, posix_flistdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010527#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010528 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
10529 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010530#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010531 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010532#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010533#ifdef HAVE_GETPRIORITY
10534 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10535#endif /* HAVE_GETPRIORITY */
10536#ifdef HAVE_SETPRIORITY
10537 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10538#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010539#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010540 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010541#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010542#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010543 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010544#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010545 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
Antoine Pitrouf3b2d882012-01-30 22:08:52 +010010546 {"replace", posix_replace, METH_VARARGS, posix_replace__doc__},
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010547 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
10548 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010550#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010552#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010553#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010554 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010555 win_symlink__doc__},
10556#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010557#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010559#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010561#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010562 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010563#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10565 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
10566 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010567#ifdef HAVE_FUTIMES
10568 {"futimes", posix_futimes, METH_VARARGS, posix_futimes__doc__},
10569#endif
10570#ifdef HAVE_LUTIMES
10571 {"lutimes", posix_lutimes, METH_VARARGS, posix_lutimes__doc__},
10572#endif
10573#ifdef HAVE_FUTIMENS
10574 {"futimens", posix_futimens, METH_VARARGS, posix_futimens__doc__},
10575#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010576#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010578#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010580#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10582 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010583#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010584#ifdef HAVE_FEXECVE
10585 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10586#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010587#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10589 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010590#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010591 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10592 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010593#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010594#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010595#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010597#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010598#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010600#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010601#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010602#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010603 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10604 {"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 +020010605#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010606#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010607 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010608#endif
10609#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010610 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010611#endif
10612#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010613 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010614#endif
10615#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010616 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010617#endif
10618#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010619 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010620#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010621 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010622#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010623 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10624 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10625#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010626#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010627#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010628 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010629#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010630#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010632#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010633#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010634 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010635#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010636#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010638#endif /* HAVE_GETEUID */
10639#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010641#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010642#ifdef HAVE_GETGROUPLIST
10643 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10644#endif
Fred Drakec9680921999-12-13 16:37:25 +000010645#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010647#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010649#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010651#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010652#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010653 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010654#endif /* HAVE_GETPPID */
10655#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010657#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010658#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010659 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010660#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010661#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010663#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010664#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010665 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010666#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010667#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010669#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010670#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010671 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10672 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010673 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010674#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010675#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010677#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010678#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010679 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010680#endif /* HAVE_SETEUID */
10681#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010682 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010683#endif /* HAVE_SETEGID */
10684#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010685 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010686#endif /* HAVE_SETREUID */
10687#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010688 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010689#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010690#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010692#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010693#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010695#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010696#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010698#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010699#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010701#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010702#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010703 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010704#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010705#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010707#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010708#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +000010709 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010710#endif /* HAVE_WAIT3 */
10711#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +000010712 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010713#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010714#if defined(HAVE_WAITID) && !defined(__APPLE__)
10715 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10716#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010717#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010718 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010719#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010720#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010722#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010723#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010725#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010726#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010728#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010729#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010730 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010731#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010732#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010733 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010734#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10736 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10737 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10738 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10739 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10740 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010741#ifdef HAVE_LOCKF
10742 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10743#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10745 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010746#ifdef HAVE_READV
10747 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10748#endif
10749#ifdef HAVE_PREAD
10750 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10751#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010753#ifdef HAVE_WRITEV
10754 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10755#endif
10756#ifdef HAVE_PWRITE
10757 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10758#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010759#ifdef HAVE_SENDFILE
10760 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10761 posix_sendfile__doc__},
10762#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
10764 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010765#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010767#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010768#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010769 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010770#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010771#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010772 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010773#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010774#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010775 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010776#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010777#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10779 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10780 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010781#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010782#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010784#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010785#ifdef HAVE_TRUNCATE
10786 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10787#endif
10788#ifdef HAVE_POSIX_FALLOCATE
10789 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10790#endif
10791#ifdef HAVE_POSIX_FADVISE
10792 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10793#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010794#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010795 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010796#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010797#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010798 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010799#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010800 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010801#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010802 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010803#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010804#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010806#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010807#ifdef HAVE_SYNC
10808 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10809#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010810#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010812#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010813#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010814#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010815 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010816#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010817#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010819#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010820#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010821 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010822#endif /* WIFSTOPPED */
10823#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010825#endif /* WIFSIGNALED */
10826#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010828#endif /* WIFEXITED */
10829#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010831#endif /* WEXITSTATUS */
10832#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010834#endif /* WTERMSIG */
10835#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010837#endif /* WSTOPSIG */
10838#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010839#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010840 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010841#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010842#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010843 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010844#endif
Fred Drakec9680921999-12-13 16:37:25 +000010845#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010846 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010847#endif
10848#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010849 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010850#endif
10851#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010853#endif
10854#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010855 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010856#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010858#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010860 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010861 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010862 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010863 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010864#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010865#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010867#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010868 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010869 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010870 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010871 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010873 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010874#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010875 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010876#endif
10877#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010878 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010879#endif
10880#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010881 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010882#endif
10883#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010884 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010885#endif
10886
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010887/* posix *at family of functions */
10888#ifdef HAVE_FACCESSAT
10889 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
10890#endif
10891#ifdef HAVE_FCHMODAT
10892 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
10893#endif /* HAVE_FCHMODAT */
10894#ifdef HAVE_FCHOWNAT
10895 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
10896#endif /* HAVE_FCHOWNAT */
10897#ifdef HAVE_FSTATAT
10898 {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
10899#endif
10900#ifdef HAVE_FUTIMESAT
10901 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
10902#endif
10903#ifdef HAVE_LINKAT
10904 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
10905#endif /* HAVE_LINKAT */
10906#ifdef HAVE_MKDIRAT
10907 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
10908#endif
10909#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
10910 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
10911#endif
10912#ifdef HAVE_OPENAT
10913 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
10914#endif
10915#ifdef HAVE_READLINKAT
10916 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
10917#endif /* HAVE_READLINKAT */
10918#ifdef HAVE_RENAMEAT
10919 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
10920#endif
10921#if HAVE_SYMLINKAT
10922 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
10923#endif /* HAVE_SYMLINKAT */
10924#ifdef HAVE_UNLINKAT
10925 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
10926#endif
10927#ifdef HAVE_UTIMENSAT
Jesus Cead03a4912011-11-08 17:28:04 +010010928 {"utimensat", (PyCFunction)posix_utimensat,
10929 METH_VARARGS | METH_KEYWORDS,
Brian Curtin569b4942011-11-07 16:09:20 -060010930 posix_utimensat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010931#endif
10932#ifdef HAVE_MKFIFOAT
10933 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
10934#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040010935#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010936 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
10937 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
10938 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
10939 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
10940 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
10941 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
10942 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
10943 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
10944 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
10945 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
10946 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
10947 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
10948#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010949 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010950};
10951
10952
Barry Warsaw4a342091996-12-19 23:50:02 +000010953static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010954ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000010955{
Victor Stinner8c62be82010-05-06 00:08:46 +000010956 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000010957}
10958
Guido van Rossumd48f2521997-12-05 22:19:34 +000010959#if defined(PYOS_OS2)
10960/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000010961static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000010962{
10963 APIRET rc;
10964 ULONG values[QSV_MAX+1];
10965 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000010966 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000010967
10968 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000010969 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000010970 Py_END_ALLOW_THREADS
10971
10972 if (rc != NO_ERROR) {
10973 os2_error(rc);
10974 return -1;
10975 }
10976
Fred Drake4d1e64b2002-04-15 19:40:07 +000010977 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
10978 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
10979 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
10980 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
10981 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
10982 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
10983 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000010984
10985 switch (values[QSV_VERSION_MINOR]) {
10986 case 0: ver = "2.00"; break;
10987 case 10: ver = "2.10"; break;
10988 case 11: ver = "2.11"; break;
10989 case 30: ver = "3.00"; break;
10990 case 40: ver = "4.00"; break;
10991 case 50: ver = "5.00"; break;
10992 default:
Tim Peters885d4572001-11-28 20:27:42 +000010993 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000010994 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000010995 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000010996 ver = &tmp[0];
10997 }
10998
10999 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011000 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011001 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011002
11003 /* Add Indicator of Which Drive was Used to Boot the System */
11004 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11005 tmp[1] = ':';
11006 tmp[2] = '\0';
11007
Fred Drake4d1e64b2002-04-15 19:40:07 +000011008 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011009}
11010#endif
11011
Brian Curtin52173d42010-12-02 18:29:18 +000011012#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011013static int
Brian Curtin52173d42010-12-02 18:29:18 +000011014enable_symlink()
11015{
11016 HANDLE tok;
11017 TOKEN_PRIVILEGES tok_priv;
11018 LUID luid;
11019 int meth_idx = 0;
11020
11021 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011022 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011023
11024 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011025 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011026
11027 tok_priv.PrivilegeCount = 1;
11028 tok_priv.Privileges[0].Luid = luid;
11029 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11030
11031 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11032 sizeof(TOKEN_PRIVILEGES),
11033 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011034 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011035
Brian Curtin3b4499c2010-12-28 14:31:47 +000011036 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11037 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011038}
11039#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11040
Barry Warsaw4a342091996-12-19 23:50:02 +000011041static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011042all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011043{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011044#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011045 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011046#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011047#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011048 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011049#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011050#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011051 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011052#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011053#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011054 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011055#endif
Fred Drakec9680921999-12-13 16:37:25 +000011056#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011057 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011058#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011059#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011060 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011061#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011062#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011063 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011064#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011065#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011066 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011067#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011068#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011069 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011070#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011071#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011072 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011073#endif
11074#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011075 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011076#endif
11077#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011078 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011079#endif
11080#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011081 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011082#endif
11083#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011084 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011085#endif
11086#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011087 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011088#endif
11089#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011090 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011091#endif
11092#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011093 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011094#endif
11095#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011096 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011097#endif
11098#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011099 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011100#endif
11101#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011102 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011103#endif
11104#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011105 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011106#endif
11107#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011108 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011109#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011110#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011111 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011112#endif
11113#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011114 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011115#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011116#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011117 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011118#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011119#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011120 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011121#endif
11122#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011123 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011124#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011125#ifdef PRIO_PROCESS
11126 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11127#endif
11128#ifdef PRIO_PGRP
11129 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11130#endif
11131#ifdef PRIO_USER
11132 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11133#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011134#ifdef O_CLOEXEC
11135 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11136#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011137/* posix - constants for *at functions */
11138#ifdef AT_SYMLINK_NOFOLLOW
11139 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11140#endif
11141#ifdef AT_EACCESS
11142 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11143#endif
11144#ifdef AT_FDCWD
11145 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11146#endif
11147#ifdef AT_REMOVEDIR
11148 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11149#endif
11150#ifdef AT_SYMLINK_FOLLOW
11151 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11152#endif
11153#ifdef UTIME_NOW
11154 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11155#endif
11156#ifdef UTIME_OMIT
11157 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11158#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011159
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011160
Tim Peters5aa91602002-01-30 05:46:57 +000011161/* MS Windows */
11162#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 /* Don't inherit in child processes. */
11164 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011165#endif
11166#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 /* Optimize for short life (keep in memory). */
11168 /* MS forgot to define this one with a non-underscore form too. */
11169 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011170#endif
11171#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 /* Automatically delete when last handle is closed. */
11173 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011174#endif
11175#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 /* Optimize for random access. */
11177 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011178#endif
11179#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011180 /* Optimize for sequential access. */
11181 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011182#endif
11183
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011184/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011185#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011186 /* Send a SIGIO signal whenever input or output
11187 becomes available on file descriptor */
11188 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011189#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011190#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011191 /* Direct disk access. */
11192 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011193#endif
11194#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011195 /* Must be a directory. */
11196 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011197#endif
11198#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011199 /* Do not follow links. */
11200 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011201#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011202#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011203 /* Do not update the access time. */
11204 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011205#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011206
Victor Stinner8c62be82010-05-06 00:08:46 +000011207 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011208#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011209 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011210#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011211#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011212 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011213#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011214#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011216#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011217#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011218 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011219#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011220#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011221 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011222#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011223#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011225#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011226#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011227 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011228#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011229#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011230 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011231#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011232#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011233 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011234#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011235#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011236 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011237#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011238#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011239 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011240#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011241#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011243#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011244#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011245 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011246#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011247#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011249#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011250#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011252#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011253#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011254 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011255#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011256#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011258#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011259
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011260 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011261#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011262 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011263#endif /* ST_RDONLY */
11264#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011265 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011266#endif /* ST_NOSUID */
11267
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011268 /* FreeBSD sendfile() constants */
11269#ifdef SF_NODISKIO
11270 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11271#endif
11272#ifdef SF_MNOWAIT
11273 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11274#endif
11275#ifdef SF_SYNC
11276 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11277#endif
11278
Ross Lagerwall7807c352011-03-17 20:20:30 +020011279 /* constants for posix_fadvise */
11280#ifdef POSIX_FADV_NORMAL
11281 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11282#endif
11283#ifdef POSIX_FADV_SEQUENTIAL
11284 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11285#endif
11286#ifdef POSIX_FADV_RANDOM
11287 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11288#endif
11289#ifdef POSIX_FADV_NOREUSE
11290 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11291#endif
11292#ifdef POSIX_FADV_WILLNEED
11293 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11294#endif
11295#ifdef POSIX_FADV_DONTNEED
11296 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11297#endif
11298
11299 /* constants for waitid */
11300#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11301 if (ins(d, "P_PID", (long)P_PID)) return -1;
11302 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11303 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11304#endif
11305#ifdef WEXITED
11306 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11307#endif
11308#ifdef WNOWAIT
11309 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11310#endif
11311#ifdef WSTOPPED
11312 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11313#endif
11314#ifdef CLD_EXITED
11315 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11316#endif
11317#ifdef CLD_DUMPED
11318 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11319#endif
11320#ifdef CLD_TRAPPED
11321 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11322#endif
11323#ifdef CLD_CONTINUED
11324 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11325#endif
11326
11327 /* constants for lockf */
11328#ifdef F_LOCK
11329 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11330#endif
11331#ifdef F_TLOCK
11332 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11333#endif
11334#ifdef F_ULOCK
11335 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11336#endif
11337#ifdef F_TEST
11338 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11339#endif
11340
11341 /* constants for futimens */
11342#ifdef UTIME_NOW
11343 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11344#endif
11345#ifdef UTIME_OMIT
11346 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11347#endif
11348
Guido van Rossum246bc171999-02-01 23:54:31 +000011349#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011350#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011351 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11352 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11353 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11354 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11355 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11356 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11357 if (ins(d, "P_PM", (long)P_PM)) return -1;
11358 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11359 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11360 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11361 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11362 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11363 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11364 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11365 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11366 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11367 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11368 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11369 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11370 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011371#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011372 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11373 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11374 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11375 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11376 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011377#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011378#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011379
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011380#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011381 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011382 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11383 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11384#ifdef SCHED_SPORADIC
11385 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11386#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011387#ifdef SCHED_BATCH
11388 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11389#endif
11390#ifdef SCHED_IDLE
11391 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11392#endif
11393#ifdef SCHED_RESET_ON_FORK
11394 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11395#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011396#ifdef SCHED_SYS
11397 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11398#endif
11399#ifdef SCHED_IA
11400 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11401#endif
11402#ifdef SCHED_FSS
11403 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11404#endif
11405#ifdef SCHED_FX
11406 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11407#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011408#endif
11409
Benjamin Peterson9428d532011-09-14 11:45:52 -040011410#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011411 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11412 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11413 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11414#endif
11415
Victor Stinner8b905bd2011-10-25 13:34:04 +020011416#ifdef RTLD_LAZY
11417 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11418#endif
11419#ifdef RTLD_NOW
11420 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11421#endif
11422#ifdef RTLD_GLOBAL
11423 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11424#endif
11425#ifdef RTLD_LOCAL
11426 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11427#endif
11428#ifdef RTLD_NODELETE
11429 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11430#endif
11431#ifdef RTLD_NOLOAD
11432 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11433#endif
11434#ifdef RTLD_DEEPBIND
11435 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11436#endif
11437
Guido van Rossumd48f2521997-12-05 22:19:34 +000011438#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011439 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011440#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011441 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011442}
11443
11444
Tim Peters5aa91602002-01-30 05:46:57 +000011445#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011446#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011447#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011448
11449#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011450#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011451#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011452
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011453#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011454#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011455#define MODNAME "posix"
11456#endif
11457
Martin v. Löwis1a214512008-06-11 05:26:20 +000011458static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011459 PyModuleDef_HEAD_INIT,
11460 MODNAME,
11461 posix__doc__,
11462 -1,
11463 posix_methods,
11464 NULL,
11465 NULL,
11466 NULL,
11467 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011468};
11469
11470
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011471PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011472INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011473{
Victor Stinner8c62be82010-05-06 00:08:46 +000011474 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011475
Brian Curtin52173d42010-12-02 18:29:18 +000011476#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011477 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011478#endif
11479
Victor Stinner8c62be82010-05-06 00:08:46 +000011480 m = PyModule_Create(&posixmodule);
11481 if (m == NULL)
11482 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011483
Victor Stinner8c62be82010-05-06 00:08:46 +000011484 /* Initialize environ dictionary */
11485 v = convertenviron();
11486 Py_XINCREF(v);
11487 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11488 return NULL;
11489 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011490
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 if (all_ins(m))
11492 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011493
Victor Stinner8c62be82010-05-06 00:08:46 +000011494 if (setup_confname_tables(m))
11495 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011496
Victor Stinner8c62be82010-05-06 00:08:46 +000011497 Py_INCREF(PyExc_OSError);
11498 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011499
Benjamin Peterson2740af82011-08-02 17:41:34 -050011500#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011501 if (PyType_Ready(&cpu_set_type) < 0)
11502 return NULL;
11503 Py_INCREF(&cpu_set_type);
11504 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011505#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011506
Guido van Rossumb3d39562000-01-31 18:41:26 +000011507#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011508 if (posix_putenv_garbage == NULL)
11509 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011510#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011511
Victor Stinner8c62be82010-05-06 00:08:46 +000011512 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011513#if defined(HAVE_WAITID) && !defined(__APPLE__)
11514 waitid_result_desc.name = MODNAME ".waitid_result";
11515 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11516#endif
11517
Victor Stinner8c62be82010-05-06 00:08:46 +000011518 stat_result_desc.name = MODNAME ".stat_result";
11519 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11520 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11521 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11522 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11523 structseq_new = StatResultType.tp_new;
11524 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011525
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 statvfs_result_desc.name = MODNAME ".statvfs_result";
11527 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011528#ifdef NEED_TICKS_PER_SECOND
11529# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011530 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011531# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011533# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011534 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011535# endif
11536#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011537
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011538#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011539 sched_param_desc.name = MODNAME ".sched_param";
11540 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11541 SchedParamType.tp_new = sched_param_new;
11542#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011544#if defined(HAVE_WAITID) && !defined(__APPLE__)
11545 Py_INCREF((PyObject*) &WaitidResultType);
11546 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11547#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011548 Py_INCREF((PyObject*) &StatResultType);
11549 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11550 Py_INCREF((PyObject*) &StatVFSResultType);
11551 PyModule_AddObject(m, "statvfs_result",
11552 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011553
11554#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011555 Py_INCREF(&SchedParamType);
11556 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011557#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011558 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011559
11560#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011561 /*
11562 * Step 2 of weak-linking support on Mac OS X.
11563 *
11564 * The code below removes functions that are not available on the
11565 * currently active platform.
11566 *
11567 * This block allow one to use a python binary that was build on
11568 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11569 * OSX 10.4.
11570 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011571#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011572 if (fstatvfs == NULL) {
11573 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11574 return NULL;
11575 }
11576 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011577#endif /* HAVE_FSTATVFS */
11578
11579#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 if (statvfs == NULL) {
11581 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11582 return NULL;
11583 }
11584 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011585#endif /* HAVE_STATVFS */
11586
11587# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 if (lchown == NULL) {
11589 if (PyObject_DelAttrString(m, "lchown") == -1) {
11590 return NULL;
11591 }
11592 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011593#endif /* HAVE_LCHOWN */
11594
11595
11596#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +000011597 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011598
Guido van Rossumb6775db1994-08-01 11:34:53 +000011599}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011600
11601#ifdef __cplusplus
11602}
11603#endif