blob: 01544b6258687067a903aa21aa9d76a2685c060c [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000019 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000031
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034#endif /* defined(__VMS) */
35
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000036#ifdef __cplusplus
37extern "C" {
38#endif
39
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000040PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000041"This module provides access to operating system functionality that is\n\
42standardized by the C Standard and the POSIX standard (a thinly\n\
43disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000044corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000046
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000047#if defined(PYOS_OS2)
48#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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif /* HAVE_SYS_TYPES_H */
65
66#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000069
Guido van Rossum36bc6801995-06-14 22:54:23 +000070#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000071#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000072#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000073
Thomas Wouters0e3f5912006-08-11 14:57:12 +000074#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000075#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000076#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000077
Guido van Rossumb6775db1994-08-01 11:34:53 +000078#ifdef HAVE_FCNTL_H
79#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000080#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000081
Guido van Rossuma6535fd2001-10-18 19:44:10 +000082#ifdef HAVE_GRP_H
83#include <grp.h>
84#endif
85
Barry Warsaw5676bd12003-01-07 20:57:09 +000086#ifdef HAVE_SYSEXITS_H
87#include <sysexits.h>
88#endif /* HAVE_SYSEXITS_H */
89
Anthony Baxter8a560de2004-10-13 15:30:56 +000090#ifdef HAVE_SYS_LOADAVG_H
91#include <sys/loadavg.h>
92#endif
93
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000094#ifdef HAVE_LANGINFO_H
95#include <langinfo.h>
96#endif
97
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000098#ifdef HAVE_SYS_SENDFILE_H
99#include <sys/sendfile.h>
100#endif
101
102#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
103#ifdef HAVE_SYS_SOCKET_H
104#include <sys/socket.h>
105#endif
106
107#ifdef HAVE_SYS_UIO_H
108#include <sys/uio.h>
109#endif
110#endif
111
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000113/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000114#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000115#include <process.h>
116#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000117#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#define HAVE_GETCWD 1
119#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000120#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000121#if defined(__OS2__)
122#define HAVE_EXECV 1
123#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000124#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#include <process.h>
126#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000127#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128#define HAVE_EXECV 1
129#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#define HAVE_OPENDIR 1
131#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000132#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000133#define HAVE_WAIT 1
134#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000135#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000136#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000137#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000138#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#define HAVE_EXECV 1
141#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000142#define HAVE_SYSTEM 1
143#define HAVE_CWAIT 1
144#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000145#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000146#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000147#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
148/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150/* Unix functions that the configure script doesn't check for */
151#define HAVE_EXECV 1
152#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000154#define HAVE_FORK1 1
155#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#define HAVE_GETCWD 1
157#define HAVE_GETEGID 1
158#define HAVE_GETEUID 1
159#define HAVE_GETGID 1
160#define HAVE_GETPPID 1
161#define HAVE_GETUID 1
162#define HAVE_KILL 1
163#define HAVE_OPENDIR 1
164#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000167#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000168#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000169#endif /* _MSC_VER */
170#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000171#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000172#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000173
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000174#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000175
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000176#if defined(__sgi)&&_COMPILER_VERSION>=700
177/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
178 (default) */
179extern char *ctermid_r(char *);
180#endif
181
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000182#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000186#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000188#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000189extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000191#endif
192#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000193extern int chdir(char *);
194extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000195#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int chdir(const char *);
197extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000198#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000199#ifdef __BORLANDC__
200extern int chmod(const char *, int);
201#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000203#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000204/*#ifdef HAVE_FCHMOD
205extern int fchmod(int, mode_t);
206#endif*/
207/*#ifdef HAVE_LCHMOD
208extern int lchmod(const char *, mode_t);
209#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int chown(const char *, uid_t, gid_t);
211extern char *getcwd(char *, int);
212extern char *strerror(int);
213extern int link(const char *, const char *);
214extern int rename(const char *, const char *);
215extern int stat(const char *, struct stat *);
216extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000219#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000222#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000224
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#ifdef HAVE_UTIME_H
228#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000231#ifdef HAVE_SYS_UTIME_H
232#include <sys/utime.h>
233#define HAVE_UTIME_H /* pretend we do for the rest of this file */
234#endif /* HAVE_SYS_UTIME_H */
235
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#ifdef HAVE_SYS_TIMES_H
237#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
240#ifdef HAVE_SYS_PARAM_H
241#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000242#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243
244#ifdef HAVE_SYS_UTSNAME_H
245#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#define NAMLEN(dirent) strlen((dirent)->d_name)
251#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000252#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000253#include <direct.h>
254#define NAMLEN(dirent) strlen((dirent)->d_name)
255#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000257#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000258#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000259#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000261#endif
262#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000264#endif
265#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000267#endif
268#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000270#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000271#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000273#endif
274#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000276#endif
277#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000279#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000280#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000281#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000282#endif
283#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000284#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000285#endif
286#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000287#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000288#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000289#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000290#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000292#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000293#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000294#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
295#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000296static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000297#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000298#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299
Guido van Rossumd48f2521997-12-05 22:19:34 +0000300#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000302#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303
Tim Petersbc2e10e2002-03-03 23:17:02 +0000304#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000305#if defined(PATH_MAX) && PATH_MAX > 1024
306#define MAXPATHLEN PATH_MAX
307#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000309#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000310#endif /* MAXPATHLEN */
311
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000312#ifdef UNION_WAIT
313/* Emulate some macros on systems that have a union instead of macros */
314
315#ifndef WIFEXITED
316#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
317#endif
318
319#ifndef WEXITSTATUS
320#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
321#endif
322
323#ifndef WTERMSIG
324#define WTERMSIG(u_wait) ((u_wait).w_termsig)
325#endif
326
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000327#define WAIT_TYPE union wait
328#define WAIT_STATUS_INT(s) (s.w_status)
329
330#else /* !UNION_WAIT */
331#define WAIT_TYPE int
332#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000333#endif /* UNION_WAIT */
334
Greg Wardb48bc172000-03-01 21:51:56 +0000335/* Don't use the "_r" form if we don't need it (also, won't have a
336 prototype for it, at least on Solaris -- maybe others as well?). */
337#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
338#define USE_CTERMID_R
339#endif
340
Fred Drake699f3522000-06-29 21:12:41 +0000341/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000342#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000343#undef FSTAT
344#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000345#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000346# define STAT win32_stat
347# define FSTAT win32_fstat
348# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000349#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000350# define STAT stat
351# define FSTAT fstat
352# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000353#endif
354
Tim Peters11b23062003-04-23 02:39:17 +0000355#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000356#include <sys/mkdev.h>
357#else
358#if defined(MAJOR_IN_SYSMACROS)
359#include <sys/sysmacros.h>
360#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000361#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
362#include <sys/mkdev.h>
363#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000364#endif
Fred Drake699f3522000-06-29 21:12:41 +0000365
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000366int
367PyParse_off_t(PyObject* arg, void* addr)
368{
369#if !defined(HAVE_LARGEFILE_SUPPORT)
370 *((off_t*)addr) = PyLong_AsLong(arg);
371#else
372 *((off_t*)addr) = PyLong_Check(arg) ? PyLong_AsLongLong(arg)
373 : PyLong_AsLong(arg);
374#endif
375 if (PyErr_Occurred())
376 return 0;
377 return 1;
378}
379
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000380#if defined _MSC_VER && _MSC_VER >= 1400
381/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
382 * valid and throw an assertion if it isn't.
383 * Normally, an invalid fd is likely to be a C program error and therefore
384 * an assertion can be useful, but it does contradict the POSIX standard
385 * which for write(2) states:
386 * "Otherwise, -1 shall be returned and errno set to indicate the error."
387 * "[EBADF] The fildes argument is not a valid file descriptor open for
388 * writing."
389 * Furthermore, python allows the user to enter any old integer
390 * as a fd and should merely raise a python exception on error.
391 * The Microsoft CRT doesn't provide an official way to check for the
392 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000393 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000394 * internal structures involved.
395 * The structures below must be updated for each version of visual studio
396 * according to the file internal.h in the CRT source, until MS comes
397 * up with a less hacky way to do this.
398 * (all of this is to avoid globally modifying the CRT behaviour using
399 * _set_invalid_parameter_handler() and _CrtSetReportMode())
400 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000401/* The actual size of the structure is determined at runtime.
402 * Only the first items must be present.
403 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000404typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000405 intptr_t osfhnd;
406 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000407} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000408
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000409extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000410#define IOINFO_L2E 5
411#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
412#define IOINFO_ARRAYS 64
413#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
414#define FOPEN 0x01
415#define _NO_CONSOLE_FILENO (intptr_t)-2
416
417/* This function emulates what the windows CRT does to validate file handles */
418int
419_PyVerify_fd(int fd)
420{
Victor Stinner8c62be82010-05-06 00:08:46 +0000421 const int i1 = fd >> IOINFO_L2E;
422 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000423
Antoine Pitrou22e41552010-08-15 18:07:50 +0000424 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000425
Victor Stinner8c62be82010-05-06 00:08:46 +0000426 /* Determine the actual size of the ioinfo structure,
427 * as used by the CRT loaded in memory
428 */
429 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
430 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
431 }
432 if (sizeof_ioinfo == 0) {
433 /* This should not happen... */
434 goto fail;
435 }
436
437 /* See that it isn't a special CLEAR fileno */
438 if (fd != _NO_CONSOLE_FILENO) {
439 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
440 * we check pointer validity and other info
441 */
442 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
443 /* finally, check that the file is open */
444 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
445 if (info->osfile & FOPEN) {
446 return 1;
447 }
448 }
449 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000450 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000451 errno = EBADF;
452 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000453}
454
455/* the special case of checking dup2. The target fd must be in a sensible range */
456static int
457_PyVerify_fd_dup2(int fd1, int fd2)
458{
Victor Stinner8c62be82010-05-06 00:08:46 +0000459 if (!_PyVerify_fd(fd1))
460 return 0;
461 if (fd2 == _NO_CONSOLE_FILENO)
462 return 0;
463 if ((unsigned)fd2 < _NHANDLE_)
464 return 1;
465 else
466 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000467}
468#else
469/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
470#define _PyVerify_fd_dup2(A, B) (1)
471#endif
472
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000473#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000474/* The following structure was copied from
475 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
476 include doesn't seem to be present in the Windows SDK (at least as included
477 with Visual Studio Express). */
478typedef struct _REPARSE_DATA_BUFFER {
479 ULONG ReparseTag;
480 USHORT ReparseDataLength;
481 USHORT Reserved;
482 union {
483 struct {
484 USHORT SubstituteNameOffset;
485 USHORT SubstituteNameLength;
486 USHORT PrintNameOffset;
487 USHORT PrintNameLength;
488 ULONG Flags;
489 WCHAR PathBuffer[1];
490 } SymbolicLinkReparseBuffer;
491
492 struct {
493 USHORT SubstituteNameOffset;
494 USHORT SubstituteNameLength;
495 USHORT PrintNameOffset;
496 USHORT PrintNameLength;
497 WCHAR PathBuffer[1];
498 } MountPointReparseBuffer;
499
500 struct {
501 UCHAR DataBuffer[1];
502 } GenericReparseBuffer;
503 };
504} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
505
506#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
507 GenericReparseBuffer)
508#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
509
510static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +0000511win32_read_link(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000512{
513 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
514 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
515 DWORD n_bytes_returned;
516 const wchar_t *ptr;
517 wchar_t *buf;
518 size_t len;
519
520 if (0 == DeviceIoControl(
521 reparse_point_handle,
522 FSCTL_GET_REPARSE_POINT,
523 NULL, 0, /* in buffer */
524 target_buffer, sizeof(target_buffer),
525 &n_bytes_returned,
526 NULL)) /* we're not using OVERLAPPED_IO */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +0000527 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000528
529 if (reparse_tag)
530 *reparse_tag = rdb->ReparseTag;
531
532 if (target_path) {
533 switch (rdb->ReparseTag) {
534 case IO_REPARSE_TAG_SYMLINK:
535 /* XXX: Maybe should use SubstituteName? */
536 ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer +
537 rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
538 len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR);
539 break;
540 case IO_REPARSE_TAG_MOUNT_POINT:
541 ptr = rdb->MountPointReparseBuffer.PathBuffer +
542 rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
543 len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR);
544 break;
545 default:
546 SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +0000547 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000548 }
549 buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
550 if (!buf) {
551 SetLastError(ERROR_OUTOFMEMORY);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +0000552 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000553 }
554 wcsncpy(buf, ptr, len);
555 buf[len] = L'\0';
556 if (wcsncmp(buf, L"\\??\\", 4) == 0)
557 buf[1] = L'\\';
558 *target_path = buf;
559 }
560
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +0000561 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000562}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000563#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000564
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000566#ifdef WITH_NEXT_FRAMEWORK
567/* On Darwin/MacOSX a shared library or framework has no access to
568** environ directly, we must obtain it with _NSGetEnviron().
569*/
570#include <crt_externs.h>
571static char **environ;
572#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000573extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000574#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000575
Barry Warsaw53699e91996-12-10 23:23:01 +0000576static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000577convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000578{
Victor Stinner8c62be82010-05-06 00:08:46 +0000579 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000580#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000581 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000582#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000583 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000584#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000585#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000586 APIRET rc;
587 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
588#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000589
Victor Stinner8c62be82010-05-06 00:08:46 +0000590 d = PyDict_New();
591 if (d == NULL)
592 return NULL;
593#ifdef WITH_NEXT_FRAMEWORK
594 if (environ == NULL)
595 environ = *_NSGetEnviron();
596#endif
597#ifdef MS_WINDOWS
598 /* _wenviron must be initialized in this way if the program is started
599 through main() instead of wmain(). */
600 _wgetenv(L"");
601 if (_wenviron == NULL)
602 return d;
603 /* This part ignores errors */
604 for (e = _wenviron; *e != NULL; e++) {
605 PyObject *k;
606 PyObject *v;
607 wchar_t *p = wcschr(*e, L'=');
608 if (p == NULL)
609 continue;
610 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
611 if (k == NULL) {
612 PyErr_Clear();
613 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000614 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000615 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
616 if (v == NULL) {
617 PyErr_Clear();
618 Py_DECREF(k);
619 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000620 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000621 if (PyDict_GetItem(d, k) == NULL) {
622 if (PyDict_SetItem(d, k, v) != 0)
623 PyErr_Clear();
624 }
625 Py_DECREF(k);
626 Py_DECREF(v);
627 }
628#else
629 if (environ == NULL)
630 return d;
631 /* This part ignores errors */
632 for (e = environ; *e != NULL; e++) {
633 PyObject *k;
634 PyObject *v;
635 char *p = strchr(*e, '=');
636 if (p == NULL)
637 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000638 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000639 if (k == NULL) {
640 PyErr_Clear();
641 continue;
642 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000643 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000644 if (v == NULL) {
645 PyErr_Clear();
646 Py_DECREF(k);
647 continue;
648 }
649 if (PyDict_GetItem(d, k) == NULL) {
650 if (PyDict_SetItem(d, k, v) != 0)
651 PyErr_Clear();
652 }
653 Py_DECREF(k);
654 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000655 }
656#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000657#if defined(PYOS_OS2)
658 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
659 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
660 PyObject *v = PyBytes_FromString(buffer);
661 PyDict_SetItemString(d, "BEGINLIBPATH", v);
662 Py_DECREF(v);
663 }
664 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
665 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
666 PyObject *v = PyBytes_FromString(buffer);
667 PyDict_SetItemString(d, "ENDLIBPATH", v);
668 Py_DECREF(v);
669 }
670#endif
671 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672}
673
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674/* Set a POSIX-specific error from errno, and return NULL */
675
Barry Warsawd58d7641998-07-23 16:14:40 +0000676static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000677posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000678{
Victor Stinner8c62be82010-05-06 00:08:46 +0000679 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000680}
Barry Warsawd58d7641998-07-23 16:14:40 +0000681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000682posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000683{
Victor Stinner8c62be82010-05-06 00:08:46 +0000684 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000685}
686
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000687
Mark Hammondef8b6542001-05-13 08:04:26 +0000688static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000689posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000690{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000691 PyObject *name_str, *rc;
692 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
693 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000694 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000695 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
696 name_str);
697 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000698 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000699}
700
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000701#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000702static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000703win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000704{
Victor Stinner8c62be82010-05-06 00:08:46 +0000705 /* XXX We should pass the function name along in the future.
706 (winreg.c also wants to pass the function name.)
707 This would however require an additional param to the
708 Windows error object, which is non-trivial.
709 */
710 errno = GetLastError();
711 if (filename)
712 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
713 else
714 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000715}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000716
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000717static PyObject *
718win32_error_unicode(char* function, Py_UNICODE* filename)
719{
Victor Stinner8c62be82010-05-06 00:08:46 +0000720 /* XXX - see win32_error for comments on 'function' */
721 errno = GetLastError();
722 if (filename)
723 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
724 else
725 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000726}
727
Thomas Wouters477c8d52006-05-27 19:21:47 +0000728static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000729convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000730{
Victor Stinner8c62be82010-05-06 00:08:46 +0000731 if (PyUnicode_CheckExact(*param))
732 Py_INCREF(*param);
733 else if (PyUnicode_Check(*param))
734 /* For a Unicode subtype that's not a Unicode object,
735 return a true Unicode object with the same data. */
736 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
737 PyUnicode_GET_SIZE(*param));
738 else
739 *param = PyUnicode_FromEncodedObject(*param,
740 Py_FileSystemDefaultEncoding,
741 "strict");
742 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000743}
744
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000745#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000746
Guido van Rossumd48f2521997-12-05 22:19:34 +0000747#if defined(PYOS_OS2)
748/**********************************************************************
749 * Helper Function to Trim and Format OS/2 Messages
750 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000751static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000752os2_formatmsg(char *msgbuf, int msglen, char *reason)
753{
754 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
755
756 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
757 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
758
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000759 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000760 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
761 }
762
763 /* Add Optional Reason Text */
764 if (reason) {
765 strcat(msgbuf, " : ");
766 strcat(msgbuf, reason);
767 }
768}
769
770/**********************************************************************
771 * Decode an OS/2 Operating System Error Code
772 *
773 * A convenience function to lookup an OS/2 error code and return a
774 * text message we can use to raise a Python exception.
775 *
776 * Notes:
777 * The messages for errors returned from the OS/2 kernel reside in
778 * the file OSO001.MSG in the \OS2 directory hierarchy.
779 *
780 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000781static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000782os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
783{
784 APIRET rc;
785 ULONG msglen;
786
787 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
788 Py_BEGIN_ALLOW_THREADS
789 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
790 errorcode, "oso001.msg", &msglen);
791 Py_END_ALLOW_THREADS
792
793 if (rc == NO_ERROR)
794 os2_formatmsg(msgbuf, msglen, reason);
795 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000796 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000797 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000798
799 return msgbuf;
800}
801
802/* Set an OS/2-specific error and return NULL. OS/2 kernel
803 errors are not in a global variable e.g. 'errno' nor are
804 they congruent with posix error numbers. */
805
Victor Stinner8c62be82010-05-06 00:08:46 +0000806static PyObject *
807os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000808{
809 char text[1024];
810 PyObject *v;
811
812 os2_strerror(text, sizeof(text), code, "");
813
814 v = Py_BuildValue("(is)", code, text);
815 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000816 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000817 Py_DECREF(v);
818 }
819 return NULL; /* Signal to Python that an Exception is Pending */
820}
821
822#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000823
824/* POSIX generic methods */
825
Barry Warsaw53699e91996-12-10 23:23:01 +0000826static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000827posix_fildes(PyObject *fdobj, int (*func)(int))
828{
Victor Stinner8c62be82010-05-06 00:08:46 +0000829 int fd;
830 int res;
831 fd = PyObject_AsFileDescriptor(fdobj);
832 if (fd < 0)
833 return NULL;
834 if (!_PyVerify_fd(fd))
835 return posix_error();
836 Py_BEGIN_ALLOW_THREADS
837 res = (*func)(fd);
838 Py_END_ALLOW_THREADS
839 if (res < 0)
840 return posix_error();
841 Py_INCREF(Py_None);
842 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000843}
Guido van Rossum21142a01999-01-08 21:05:37 +0000844
845static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000846posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000847{
Victor Stinner8c62be82010-05-06 00:08:46 +0000848 PyObject *opath1 = NULL;
849 char *path1;
850 int res;
851 if (!PyArg_ParseTuple(args, format,
852 PyUnicode_FSConverter, &opath1))
853 return NULL;
854 path1 = PyBytes_AsString(opath1);
855 Py_BEGIN_ALLOW_THREADS
856 res = (*func)(path1);
857 Py_END_ALLOW_THREADS
858 if (res < 0)
859 return posix_error_with_allocated_filename(opath1);
860 Py_DECREF(opath1);
861 Py_INCREF(Py_None);
862 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000863}
864
Barry Warsaw53699e91996-12-10 23:23:01 +0000865static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000866posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000867 char *format,
868 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000869{
Victor Stinner8c62be82010-05-06 00:08:46 +0000870 PyObject *opath1 = NULL, *opath2 = NULL;
871 char *path1, *path2;
872 int res;
873 if (!PyArg_ParseTuple(args, format,
874 PyUnicode_FSConverter, &opath1,
875 PyUnicode_FSConverter, &opath2)) {
876 return NULL;
877 }
878 path1 = PyBytes_AsString(opath1);
879 path2 = PyBytes_AsString(opath2);
880 Py_BEGIN_ALLOW_THREADS
881 res = (*func)(path1, path2);
882 Py_END_ALLOW_THREADS
883 Py_DECREF(opath1);
884 Py_DECREF(opath2);
885 if (res != 0)
886 /* XXX how to report both path1 and path2??? */
887 return posix_error();
888 Py_INCREF(Py_None);
889 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000890}
891
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000892#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000893static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000894win32_1str(PyObject* args, char* func,
895 char* format, BOOL (__stdcall *funcA)(LPCSTR),
896 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000897{
Victor Stinner8c62be82010-05-06 00:08:46 +0000898 PyObject *uni;
899 char *ansi;
900 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000901
Victor Stinner8c62be82010-05-06 00:08:46 +0000902 if (!PyArg_ParseTuple(args, wformat, &uni))
903 PyErr_Clear();
904 else {
905 Py_BEGIN_ALLOW_THREADS
906 result = funcW(PyUnicode_AsUnicode(uni));
907 Py_END_ALLOW_THREADS
908 if (!result)
909 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
910 Py_INCREF(Py_None);
911 return Py_None;
912 }
913 if (!PyArg_ParseTuple(args, format, &ansi))
914 return NULL;
915 Py_BEGIN_ALLOW_THREADS
916 result = funcA(ansi);
917 Py_END_ALLOW_THREADS
918 if (!result)
919 return win32_error(func, ansi);
920 Py_INCREF(Py_None);
921 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000922
923}
924
925/* This is a reimplementation of the C library's chdir function,
926 but one that produces Win32 errors instead of DOS error codes.
927 chdir is essentially a wrapper around SetCurrentDirectory; however,
928 it also needs to set "magic" environment variables indicating
929 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000930static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000931win32_chdir(LPCSTR path)
932{
Victor Stinner8c62be82010-05-06 00:08:46 +0000933 char new_path[MAX_PATH+1];
934 int result;
935 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000936
Victor Stinner8c62be82010-05-06 00:08:46 +0000937 if(!SetCurrentDirectoryA(path))
938 return FALSE;
939 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
940 if (!result)
941 return FALSE;
942 /* In the ANSI API, there should not be any paths longer
943 than MAX_PATH. */
944 assert(result <= MAX_PATH+1);
945 if (strncmp(new_path, "\\\\", 2) == 0 ||
946 strncmp(new_path, "//", 2) == 0)
947 /* UNC path, nothing to do. */
948 return TRUE;
949 env[1] = new_path[0];
950 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000951}
952
953/* The Unicode version differs from the ANSI version
954 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000955static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000956win32_wchdir(LPCWSTR path)
957{
Victor Stinner8c62be82010-05-06 00:08:46 +0000958 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
959 int result;
960 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000961
Victor Stinner8c62be82010-05-06 00:08:46 +0000962 if(!SetCurrentDirectoryW(path))
963 return FALSE;
964 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
965 if (!result)
966 return FALSE;
967 if (result > MAX_PATH+1) {
968 new_path = malloc(result * sizeof(wchar_t));
969 if (!new_path) {
970 SetLastError(ERROR_OUTOFMEMORY);
971 return FALSE;
972 }
973 result = GetCurrentDirectoryW(result, new_path);
974 if (!result) {
975 free(new_path);
976 return FALSE;
977 }
978 }
979 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
980 wcsncmp(new_path, L"//", 2) == 0)
981 /* UNC path, nothing to do. */
982 return TRUE;
983 env[1] = new_path[0];
984 result = SetEnvironmentVariableW(env, new_path);
985 if (new_path != _new_path)
986 free(new_path);
987 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000988}
989#endif
990
Martin v. Löwis14694662006-02-03 12:54:16 +0000991#ifdef MS_WINDOWS
992/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
993 - time stamps are restricted to second resolution
994 - file modification times suffer from forth-and-back conversions between
995 UTC and local time
996 Therefore, we implement our own stat, based on the Win32 API directly.
997*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000998#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000999
1000struct win32_stat{
1001 int st_dev;
1002 __int64 st_ino;
1003 unsigned short st_mode;
1004 int st_nlink;
1005 int st_uid;
1006 int st_gid;
1007 int st_rdev;
1008 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001009 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001010 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001011 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001012 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001013 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001014 int st_ctime_nsec;
1015};
1016
1017static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1018
1019static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001020FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001021{
Victor Stinner8c62be82010-05-06 00:08:46 +00001022 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1023 /* Cannot simply cast and dereference in_ptr,
1024 since it might not be aligned properly */
1025 __int64 in;
1026 memcpy(&in, in_ptr, sizeof(in));
1027 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001028 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001029}
1030
Thomas Wouters477c8d52006-05-27 19:21:47 +00001031static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001032time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001033{
Victor Stinner8c62be82010-05-06 00:08:46 +00001034 /* XXX endianness */
1035 __int64 out;
1036 out = time_in + secs_between_epochs;
1037 out = out * 10000000 + nsec_in / 100;
1038 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001039}
1040
Martin v. Löwis14694662006-02-03 12:54:16 +00001041/* Below, we *know* that ugo+r is 0444 */
1042#if _S_IREAD != 0400
1043#error Unsupported C library
1044#endif
1045static int
1046attributes_to_mode(DWORD attr)
1047{
Victor Stinner8c62be82010-05-06 00:08:46 +00001048 int m = 0;
1049 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1050 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1051 else
1052 m |= _S_IFREG;
1053 if (attr & FILE_ATTRIBUTE_READONLY)
1054 m |= 0444;
1055 else
1056 m |= 0666;
1057 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001058}
1059
1060static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001061attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001062{
Victor Stinner8c62be82010-05-06 00:08:46 +00001063 memset(result, 0, sizeof(*result));
1064 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1065 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1066 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1067 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1068 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001069 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001070 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001071 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1072 /* first clear the S_IFMT bits */
1073 result->st_mode ^= (result->st_mode & 0170000);
1074 /* now set the bits that make this a symlink */
1075 result->st_mode |= 0120000;
1076 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001077
Victor Stinner8c62be82010-05-06 00:08:46 +00001078 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001079}
1080
Guido van Rossumd8faa362007-04-27 19:54:29 +00001081static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001082attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001083{
Victor Stinner8c62be82010-05-06 00:08:46 +00001084 HANDLE hFindFile;
1085 WIN32_FIND_DATAA FileData;
1086 hFindFile = FindFirstFileA(pszFile, &FileData);
1087 if (hFindFile == INVALID_HANDLE_VALUE)
1088 return FALSE;
1089 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001090 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001091 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001092 info->dwFileAttributes = FileData.dwFileAttributes;
1093 info->ftCreationTime = FileData.ftCreationTime;
1094 info->ftLastAccessTime = FileData.ftLastAccessTime;
1095 info->ftLastWriteTime = FileData.ftLastWriteTime;
1096 info->nFileSizeHigh = FileData.nFileSizeHigh;
1097 info->nFileSizeLow = FileData.nFileSizeLow;
1098/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001099 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1100 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001102}
1103
1104static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001105attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001106{
Victor Stinner8c62be82010-05-06 00:08:46 +00001107 HANDLE hFindFile;
1108 WIN32_FIND_DATAW FileData;
1109 hFindFile = FindFirstFileW(pszFile, &FileData);
1110 if (hFindFile == INVALID_HANDLE_VALUE)
1111 return FALSE;
1112 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001113 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001114 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001115 info->dwFileAttributes = FileData.dwFileAttributes;
1116 info->ftCreationTime = FileData.ftCreationTime;
1117 info->ftLastAccessTime = FileData.ftLastAccessTime;
1118 info->ftLastWriteTime = FileData.ftLastWriteTime;
1119 info->nFileSizeHigh = FileData.nFileSizeHigh;
1120 info->nFileSizeLow = FileData.nFileSizeLow;
1121/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001122 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1123 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001124 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001125}
1126
Brian Curtinf5e76d02010-11-24 13:14:05 +00001127#ifndef SYMLOOP_MAX
1128#define SYMLOOP_MAX ( 88 )
1129#endif
1130
1131static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001132win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001133
1134static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001135win32_xstat_impl(const char *path, struct win32_stat *result, BOOL traverse, int depth)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001136{
1137 int code;
1138 HANDLE hFile;
1139 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001140 ULONG reparse_tag = 0;
Hirokazu Yamamoto74673512010-12-05 02:48:08 +00001141 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001142 const char *dot;
1143
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001144 if (depth > SYMLOOP_MAX) {
1145 SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */
1146 return -1;
1147 }
1148
Brian Curtinf5e76d02010-11-24 13:14:05 +00001149 hFile = CreateFileA(
1150 path,
1151 0, /* desired access */
1152 0, /* share mode */
1153 NULL, /* security attributes */
1154 OPEN_EXISTING,
1155 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1156 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1157 NULL);
1158
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001159 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001160 /* Either the target doesn't exist, or we don't have access to
1161 get a handle to it. If the former, we need to return an error.
1162 If the latter, we can use attributes_from_dir. */
1163 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001164 return -1;
1165 /* Could not get attributes on open file. Fall back to
1166 reading the directory. */
1167 if (!attributes_from_dir(path, &info, &reparse_tag))
1168 /* Very strange. This should not fail now */
1169 return -1;
1170 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1171 if (traverse) {
1172 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001173 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001174 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001175 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001176 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001177 } else {
1178 if (!GetFileInformationByHandle(hFile, &info)) {
1179 CloseHandle(hFile);
1180 return -1;;
1181 }
1182 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1183 code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL);
1184 CloseHandle(hFile);
1185 if (code < 0)
1186 return code;
1187 if (traverse) {
1188 code = win32_xstat_impl_w(target_path, result, traverse, depth + 1);
1189 free(target_path);
1190 return code;
1191 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001192 } else
1193 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001194 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001195 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001196
1197 /* Set S_IEXEC if it is an .exe, .bat, ... */
1198 dot = strrchr(path, '.');
1199 if (dot) {
1200 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1201 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1202 result->st_mode |= 0111;
1203 }
1204 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001205}
1206
1207static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001208win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001209{
1210 int code;
1211 HANDLE hFile;
1212 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001213 ULONG reparse_tag = 0;
1214 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001215 const wchar_t *dot;
1216
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001217 if (depth > SYMLOOP_MAX) {
1218 SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */
1219 return -1;
1220 }
1221
Brian Curtinf5e76d02010-11-24 13:14:05 +00001222 hFile = CreateFileW(
1223 path,
1224 0, /* desired access */
1225 0, /* share mode */
1226 NULL, /* security attributes */
1227 OPEN_EXISTING,
1228 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1229 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1230 NULL);
1231
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001232 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001233 /* Either the target doesn't exist, or we don't have access to
1234 get a handle to it. If the former, we need to return an error.
1235 If the latter, we can use attributes_from_dir. */
1236 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001237 return -1;
1238 /* Could not get attributes on open file. Fall back to
1239 reading the directory. */
1240 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1241 /* Very strange. This should not fail now */
1242 return -1;
1243 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1244 if (traverse) {
1245 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001246 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001247 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001248 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001249 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001250 } else {
1251 if (!GetFileInformationByHandle(hFile, &info)) {
1252 CloseHandle(hFile);
1253 return -1;;
1254 }
1255 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1256 code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL);
1257 CloseHandle(hFile);
1258 if (code < 0)
1259 return code;
1260 if (traverse) {
1261 code = win32_xstat_impl_w(target_path, result, traverse, depth + 1);
1262 free(target_path);
1263 return code;
1264 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001265 } else
1266 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001267 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001268 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001269
1270 /* Set S_IEXEC if it is an .exe, .bat, ... */
1271 dot = wcsrchr(path, '.');
1272 if (dot) {
1273 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1274 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1275 result->st_mode |= 0111;
1276 }
1277 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001278}
1279
1280static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001281win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001282{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001283 /* Protocol violation: we explicitly clear errno, instead of
1284 setting it to a POSIX error. Callers should use GetLastError. */
1285 int code = win32_xstat_impl(path, result, traverse, 0);
1286 errno = 0;
1287 return code;
1288}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001289
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001290static int
1291win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1292{
1293 /* Protocol violation: we explicitly clear errno, instead of
1294 setting it to a POSIX error. Callers should use GetLastError. */
1295 int code = win32_xstat_impl_w(path, result, traverse, 0);
1296 errno = 0;
1297 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001298}
1299
Brian Curtind40e6f72010-07-08 21:39:08 +00001300/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
1301 win32_stat_w
1302
1303 In Posix, stat automatically traverses symlinks and returns the stat
1304 structure for the target. In Windows, the equivalent GetFileAttributes by
1305 default does not traverse symlinks and instead returns attributes for
1306 the symlink.
1307
1308 Therefore, win32_lstat will get the attributes traditionally, and
1309 win32_stat will first explicitly resolve the symlink target and then will
1310 call win32_lstat on that result.
1311
1312 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
1313
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001314static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001315win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001316{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001317 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001318}
1319
Victor Stinner8c62be82010-05-06 00:08:46 +00001320static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001321win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001322{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001323 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001324}
1325
1326static int
1327win32_stat(const char* path, struct win32_stat *result)
1328{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001329 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001330}
1331
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001332static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001333win32_stat_w(const wchar_t* path, struct win32_stat *result)
1334{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001335 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001336}
1337
1338static int
1339win32_fstat(int file_number, struct win32_stat *result)
1340{
Victor Stinner8c62be82010-05-06 00:08:46 +00001341 BY_HANDLE_FILE_INFORMATION info;
1342 HANDLE h;
1343 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001344
Victor Stinner8c62be82010-05-06 00:08:46 +00001345 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001346
Victor Stinner8c62be82010-05-06 00:08:46 +00001347 /* Protocol violation: we explicitly clear errno, instead of
1348 setting it to a POSIX error. Callers should use GetLastError. */
1349 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001350
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 if (h == INVALID_HANDLE_VALUE) {
1352 /* This is really a C library error (invalid file handle).
1353 We set the Win32 error to the closes one matching. */
1354 SetLastError(ERROR_INVALID_HANDLE);
1355 return -1;
1356 }
1357 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001358
Victor Stinner8c62be82010-05-06 00:08:46 +00001359 type = GetFileType(h);
1360 if (type == FILE_TYPE_UNKNOWN) {
1361 DWORD error = GetLastError();
1362 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001363 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 }
1365 /* else: valid but unknown file */
1366 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001367
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 if (type != FILE_TYPE_DISK) {
1369 if (type == FILE_TYPE_CHAR)
1370 result->st_mode = _S_IFCHR;
1371 else if (type == FILE_TYPE_PIPE)
1372 result->st_mode = _S_IFIFO;
1373 return 0;
1374 }
1375
1376 if (!GetFileInformationByHandle(h, &info)) {
1377 return -1;
1378 }
1379
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001380 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001381 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1383 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001384}
1385
1386#endif /* MS_WINDOWS */
1387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001388PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001389"stat_result: Result from stat or lstat.\n\n\
1390This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001391 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001392or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1393\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001394Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1395or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001396\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001397See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001398
1399static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 {"st_mode", "protection bits"},
1401 {"st_ino", "inode"},
1402 {"st_dev", "device"},
1403 {"st_nlink", "number of hard links"},
1404 {"st_uid", "user ID of owner"},
1405 {"st_gid", "group ID of owner"},
1406 {"st_size", "total size, in bytes"},
1407 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1408 {NULL, "integer time of last access"},
1409 {NULL, "integer time of last modification"},
1410 {NULL, "integer time of last change"},
1411 {"st_atime", "time of last access"},
1412 {"st_mtime", "time of last modification"},
1413 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001414#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001415 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001416#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001417#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001419#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001420#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001421 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001422#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001423#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001425#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001426#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001427 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001428#endif
1429#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001431#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001433};
1434
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001435#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001436#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001437#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001438#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001439#endif
1440
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001441#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001442#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1443#else
1444#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1445#endif
1446
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001447#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001448#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1449#else
1450#define ST_RDEV_IDX ST_BLOCKS_IDX
1451#endif
1452
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001453#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1454#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1455#else
1456#define ST_FLAGS_IDX ST_RDEV_IDX
1457#endif
1458
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001459#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001460#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001461#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001462#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001463#endif
1464
1465#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1466#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1467#else
1468#define ST_BIRTHTIME_IDX ST_GEN_IDX
1469#endif
1470
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001471static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001472 "stat_result", /* name */
1473 stat_result__doc__, /* doc */
1474 stat_result_fields,
1475 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001476};
1477
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001478PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001479"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1480This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001481 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001482or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001483\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001484See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001485
1486static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001487 {"f_bsize", },
1488 {"f_frsize", },
1489 {"f_blocks", },
1490 {"f_bfree", },
1491 {"f_bavail", },
1492 {"f_files", },
1493 {"f_ffree", },
1494 {"f_favail", },
1495 {"f_flag", },
1496 {"f_namemax",},
1497 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001498};
1499
1500static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001501 "statvfs_result", /* name */
1502 statvfs_result__doc__, /* doc */
1503 statvfs_result_fields,
1504 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001505};
1506
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001507static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001508static PyTypeObject StatResultType;
1509static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001510static newfunc structseq_new;
1511
1512static PyObject *
1513statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1514{
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 PyStructSequence *result;
1516 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001517
Victor Stinner8c62be82010-05-06 00:08:46 +00001518 result = (PyStructSequence*)structseq_new(type, args, kwds);
1519 if (!result)
1520 return NULL;
1521 /* If we have been initialized from a tuple,
1522 st_?time might be set to None. Initialize it
1523 from the int slots. */
1524 for (i = 7; i <= 9; i++) {
1525 if (result->ob_item[i+3] == Py_None) {
1526 Py_DECREF(Py_None);
1527 Py_INCREF(result->ob_item[i]);
1528 result->ob_item[i+3] = result->ob_item[i];
1529 }
1530 }
1531 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001532}
1533
1534
1535
1536/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001537static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001538
1539PyDoc_STRVAR(stat_float_times__doc__,
1540"stat_float_times([newval]) -> oldval\n\n\
1541Determine whether os.[lf]stat represents time stamps as float objects.\n\
1542If newval is True, future calls to stat() return floats, if it is False,\n\
1543future calls return ints. \n\
1544If newval is omitted, return the current setting.\n");
1545
1546static PyObject*
1547stat_float_times(PyObject* self, PyObject *args)
1548{
Victor Stinner8c62be82010-05-06 00:08:46 +00001549 int newval = -1;
1550 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1551 return NULL;
1552 if (newval == -1)
1553 /* Return old value */
1554 return PyBool_FromLong(_stat_float_times);
1555 _stat_float_times = newval;
1556 Py_INCREF(Py_None);
1557 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001558}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001559
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001560static void
1561fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1562{
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001564#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001566#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001567 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001568#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 if (!ival)
1570 return;
1571 if (_stat_float_times) {
1572 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1573 } else {
1574 fval = ival;
1575 Py_INCREF(fval);
1576 }
1577 PyStructSequence_SET_ITEM(v, index, ival);
1578 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001579}
1580
Tim Peters5aa91602002-01-30 05:46:57 +00001581/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001582 (used by posix_stat() and posix_fstat()) */
1583static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001584_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001585{
Victor Stinner8c62be82010-05-06 00:08:46 +00001586 unsigned long ansec, mnsec, cnsec;
1587 PyObject *v = PyStructSequence_New(&StatResultType);
1588 if (v == NULL)
1589 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001590
Victor Stinner8c62be82010-05-06 00:08:46 +00001591 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001592#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001593 PyStructSequence_SET_ITEM(v, 1,
1594 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001595#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001596 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001597#endif
1598#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001599 PyStructSequence_SET_ITEM(v, 2,
1600 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001601#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001602 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001603#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001604 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1605 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1606 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001607#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001608 PyStructSequence_SET_ITEM(v, 6,
1609 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001610#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001611 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001612#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001613
Martin v. Löwis14694662006-02-03 12:54:16 +00001614#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001615 ansec = st->st_atim.tv_nsec;
1616 mnsec = st->st_mtim.tv_nsec;
1617 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001618#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 ansec = st->st_atimespec.tv_nsec;
1620 mnsec = st->st_mtimespec.tv_nsec;
1621 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001622#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001623 ansec = st->st_atime_nsec;
1624 mnsec = st->st_mtime_nsec;
1625 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001626#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001627 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001628#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 fill_time(v, 7, st->st_atime, ansec);
1630 fill_time(v, 8, st->st_mtime, mnsec);
1631 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001632
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001633#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001634 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1635 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001636#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001637#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001638 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1639 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001640#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001641#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001642 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1643 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001644#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001645#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001646 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1647 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001648#endif
1649#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 {
1651 PyObject *val;
1652 unsigned long bsec,bnsec;
1653 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001654#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001655 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001656#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001657 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001658#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001659 if (_stat_float_times) {
1660 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1661 } else {
1662 val = PyLong_FromLong((long)bsec);
1663 }
1664 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1665 val);
1666 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001667#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001668#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001669 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1670 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001671#endif
Fred Drake699f3522000-06-29 21:12:41 +00001672
Victor Stinner8c62be82010-05-06 00:08:46 +00001673 if (PyErr_Occurred()) {
1674 Py_DECREF(v);
1675 return NULL;
1676 }
Fred Drake699f3522000-06-29 21:12:41 +00001677
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001679}
1680
Barry Warsaw53699e91996-12-10 23:23:01 +00001681static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001682posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001683 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001684#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001685 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001686#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001688#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001689 char *wformat,
1690 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001691{
Victor Stinner8c62be82010-05-06 00:08:46 +00001692 STRUCT_STAT st;
1693 PyObject *opath;
1694 char *path;
1695 int res;
1696 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001697
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001698#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 PyUnicodeObject *po;
1700 if (PyArg_ParseTuple(args, wformat, &po)) {
1701 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001702
Victor Stinner8c62be82010-05-06 00:08:46 +00001703 Py_BEGIN_ALLOW_THREADS
1704 /* PyUnicode_AS_UNICODE result OK without
1705 thread lock as it is a simple dereference. */
1706 res = wstatfunc(wpath, &st);
1707 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001708
Victor Stinner8c62be82010-05-06 00:08:46 +00001709 if (res != 0)
1710 return win32_error_unicode("stat", wpath);
1711 return _pystat_fromstructstat(&st);
1712 }
1713 /* Drop the argument parsing error as narrow strings
1714 are also valid. */
1715 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001716#endif
1717
Victor Stinner8c62be82010-05-06 00:08:46 +00001718 if (!PyArg_ParseTuple(args, format,
1719 PyUnicode_FSConverter, &opath))
1720 return NULL;
1721 path = PyBytes_AsString(opath);
1722 Py_BEGIN_ALLOW_THREADS
1723 res = (*statfunc)(path, &st);
1724 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001725
Victor Stinner8c62be82010-05-06 00:08:46 +00001726 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001727#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001729#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001730 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001731#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 }
1733 else
1734 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001735
Victor Stinner8c62be82010-05-06 00:08:46 +00001736 Py_DECREF(opath);
1737 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001738}
1739
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001740/* POSIX methods */
1741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001742PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001743"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001744Use the real uid/gid to test for access to a path. Note that most\n\
1745operations will use the effective uid/gid, therefore this routine can\n\
1746be used in a suid/sgid environment to test if the invoking user has the\n\
1747specified access to the path. The mode argument can be F_OK to test\n\
1748existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001749
1750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001751posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001752{
Victor Stinner8c62be82010-05-06 00:08:46 +00001753 PyObject *opath;
1754 char *path;
1755 int mode;
1756
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001757#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 DWORD attr;
1759 PyUnicodeObject *po;
1760 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1761 Py_BEGIN_ALLOW_THREADS
1762 /* PyUnicode_AS_UNICODE OK without thread lock as
1763 it is a simple dereference. */
1764 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1765 Py_END_ALLOW_THREADS
1766 goto finish;
1767 }
1768 /* Drop the argument parsing error as narrow strings
1769 are also valid. */
1770 PyErr_Clear();
1771 if (!PyArg_ParseTuple(args, "O&i:access",
1772 PyUnicode_FSConverter, &opath, &mode))
1773 return NULL;
1774 path = PyBytes_AsString(opath);
1775 Py_BEGIN_ALLOW_THREADS
1776 attr = GetFileAttributesA(path);
1777 Py_END_ALLOW_THREADS
1778 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 if (attr == 0xFFFFFFFF)
1781 /* File does not exist, or cannot read attributes */
1782 return PyBool_FromLong(0);
1783 /* Access is possible if either write access wasn't requested, or
1784 the file isn't read-only, or if it's a directory, as there are
1785 no read-only directories on Windows. */
1786 return PyBool_FromLong(!(mode & 2)
1787 || !(attr & FILE_ATTRIBUTE_READONLY)
1788 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 int res;
1791 if (!PyArg_ParseTuple(args, "O&i:access",
1792 PyUnicode_FSConverter, &opath, &mode))
1793 return NULL;
1794 path = PyBytes_AsString(opath);
1795 Py_BEGIN_ALLOW_THREADS
1796 res = access(path, mode);
1797 Py_END_ALLOW_THREADS
1798 Py_DECREF(opath);
1799 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001800#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001801}
1802
Guido van Rossumd371ff11999-01-25 16:12:23 +00001803#ifndef F_OK
1804#define F_OK 0
1805#endif
1806#ifndef R_OK
1807#define R_OK 4
1808#endif
1809#ifndef W_OK
1810#define W_OK 2
1811#endif
1812#ifndef X_OK
1813#define X_OK 1
1814#endif
1815
1816#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001818"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001820
1821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001823{
Victor Stinner8c62be82010-05-06 00:08:46 +00001824 int id;
1825 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001826
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1828 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001829
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001830#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 /* file descriptor 0 only, the default input device (stdin) */
1832 if (id == 0) {
1833 ret = ttyname();
1834 }
1835 else {
1836 ret = NULL;
1837 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001838#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001840#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001841 if (ret == NULL)
1842 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001843 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001844}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001845#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001846
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001847#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001849"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001851
1852static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001853posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001854{
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 char *ret;
1856 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001857
Greg Wardb48bc172000-03-01 21:51:56 +00001858#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001860#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001862#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001863 if (ret == NULL)
1864 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001865 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001866}
1867#endif
1868
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001870"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001871Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001872
Barry Warsaw53699e91996-12-10 23:23:01 +00001873static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001874posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001875{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001876#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001877 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001878#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001880#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001882#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001883 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001884#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885}
1886
Fred Drake4d1e64b2002-04-15 19:40:07 +00001887#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001888PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001889"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001890Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001891opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001892
1893static PyObject *
1894posix_fchdir(PyObject *self, PyObject *fdobj)
1895{
Victor Stinner8c62be82010-05-06 00:08:46 +00001896 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001897}
1898#endif /* HAVE_FCHDIR */
1899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001901PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001902"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001903Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001904
Barry Warsaw53699e91996-12-10 23:23:01 +00001905static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001906posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907{
Victor Stinner8c62be82010-05-06 00:08:46 +00001908 PyObject *opath = NULL;
1909 char *path = NULL;
1910 int i;
1911 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001912#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 DWORD attr;
1914 PyUnicodeObject *po;
1915 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1916 Py_BEGIN_ALLOW_THREADS
1917 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1918 if (attr != 0xFFFFFFFF) {
1919 if (i & _S_IWRITE)
1920 attr &= ~FILE_ATTRIBUTE_READONLY;
1921 else
1922 attr |= FILE_ATTRIBUTE_READONLY;
1923 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1924 }
1925 else
1926 res = 0;
1927 Py_END_ALLOW_THREADS
1928 if (!res)
1929 return win32_error_unicode("chmod",
1930 PyUnicode_AS_UNICODE(po));
1931 Py_INCREF(Py_None);
1932 return Py_None;
1933 }
1934 /* Drop the argument parsing error as narrow strings
1935 are also valid. */
1936 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001937
Victor Stinner8c62be82010-05-06 00:08:46 +00001938 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1939 &opath, &i))
1940 return NULL;
1941 path = PyBytes_AsString(opath);
1942 Py_BEGIN_ALLOW_THREADS
1943 attr = GetFileAttributesA(path);
1944 if (attr != 0xFFFFFFFF) {
1945 if (i & _S_IWRITE)
1946 attr &= ~FILE_ATTRIBUTE_READONLY;
1947 else
1948 attr |= FILE_ATTRIBUTE_READONLY;
1949 res = SetFileAttributesA(path, attr);
1950 }
1951 else
1952 res = 0;
1953 Py_END_ALLOW_THREADS
1954 if (!res) {
1955 win32_error("chmod", path);
1956 Py_DECREF(opath);
1957 return NULL;
1958 }
1959 Py_DECREF(opath);
1960 Py_INCREF(Py_None);
1961 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001962#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001963 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1964 &opath, &i))
1965 return NULL;
1966 path = PyBytes_AsString(opath);
1967 Py_BEGIN_ALLOW_THREADS
1968 res = chmod(path, i);
1969 Py_END_ALLOW_THREADS
1970 if (res < 0)
1971 return posix_error_with_allocated_filename(opath);
1972 Py_DECREF(opath);
1973 Py_INCREF(Py_None);
1974 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001975#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001976}
1977
Christian Heimes4e30a842007-11-30 22:12:06 +00001978#ifdef HAVE_FCHMOD
1979PyDoc_STRVAR(posix_fchmod__doc__,
1980"fchmod(fd, mode)\n\n\
1981Change the access permissions of the file given by file\n\
1982descriptor fd.");
1983
1984static PyObject *
1985posix_fchmod(PyObject *self, PyObject *args)
1986{
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 int fd, mode, res;
1988 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1989 return NULL;
1990 Py_BEGIN_ALLOW_THREADS
1991 res = fchmod(fd, mode);
1992 Py_END_ALLOW_THREADS
1993 if (res < 0)
1994 return posix_error();
1995 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001996}
1997#endif /* HAVE_FCHMOD */
1998
1999#ifdef HAVE_LCHMOD
2000PyDoc_STRVAR(posix_lchmod__doc__,
2001"lchmod(path, mode)\n\n\
2002Change the access permissions of a file. If path is a symlink, this\n\
2003affects the link itself rather than the target.");
2004
2005static PyObject *
2006posix_lchmod(PyObject *self, PyObject *args)
2007{
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 PyObject *opath;
2009 char *path;
2010 int i;
2011 int res;
2012 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2013 &opath, &i))
2014 return NULL;
2015 path = PyBytes_AsString(opath);
2016 Py_BEGIN_ALLOW_THREADS
2017 res = lchmod(path, i);
2018 Py_END_ALLOW_THREADS
2019 if (res < 0)
2020 return posix_error_with_allocated_filename(opath);
2021 Py_DECREF(opath);
2022 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002023}
2024#endif /* HAVE_LCHMOD */
2025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002026
Thomas Wouterscf297e42007-02-23 15:07:44 +00002027#ifdef HAVE_CHFLAGS
2028PyDoc_STRVAR(posix_chflags__doc__,
2029"chflags(path, flags)\n\n\
2030Set file flags.");
2031
2032static PyObject *
2033posix_chflags(PyObject *self, PyObject *args)
2034{
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 PyObject *opath;
2036 char *path;
2037 unsigned long flags;
2038 int res;
2039 if (!PyArg_ParseTuple(args, "O&k:chflags",
2040 PyUnicode_FSConverter, &opath, &flags))
2041 return NULL;
2042 path = PyBytes_AsString(opath);
2043 Py_BEGIN_ALLOW_THREADS
2044 res = chflags(path, flags);
2045 Py_END_ALLOW_THREADS
2046 if (res < 0)
2047 return posix_error_with_allocated_filename(opath);
2048 Py_DECREF(opath);
2049 Py_INCREF(Py_None);
2050 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002051}
2052#endif /* HAVE_CHFLAGS */
2053
2054#ifdef HAVE_LCHFLAGS
2055PyDoc_STRVAR(posix_lchflags__doc__,
2056"lchflags(path, flags)\n\n\
2057Set file flags.\n\
2058This function will not follow symbolic links.");
2059
2060static PyObject *
2061posix_lchflags(PyObject *self, PyObject *args)
2062{
Victor Stinner8c62be82010-05-06 00:08:46 +00002063 PyObject *opath;
2064 char *path;
2065 unsigned long flags;
2066 int res;
2067 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2068 PyUnicode_FSConverter, &opath, &flags))
2069 return NULL;
2070 path = PyBytes_AsString(opath);
2071 Py_BEGIN_ALLOW_THREADS
2072 res = lchflags(path, flags);
2073 Py_END_ALLOW_THREADS
2074 if (res < 0)
2075 return posix_error_with_allocated_filename(opath);
2076 Py_DECREF(opath);
2077 Py_INCREF(Py_None);
2078 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002079}
2080#endif /* HAVE_LCHFLAGS */
2081
Martin v. Löwis244edc82001-10-04 22:44:26 +00002082#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002083PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002084"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002085Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002086
2087static PyObject *
2088posix_chroot(PyObject *self, PyObject *args)
2089{
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002091}
2092#endif
2093
Guido van Rossum21142a01999-01-08 21:05:37 +00002094#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002096"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002097force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002098
2099static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002100posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002101{
Stefan Krah0e803b32010-11-26 16:16:47 +00002102 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002103}
2104#endif /* HAVE_FSYNC */
2105
2106#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002107
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002108#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002109extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2110#endif
2111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002112PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002113"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002114force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002115 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002116
2117static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002118posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002119{
Stefan Krah0e803b32010-11-26 16:16:47 +00002120 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002121}
2122#endif /* HAVE_FDATASYNC */
2123
2124
Fredrik Lundh10723342000-07-10 16:38:09 +00002125#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002126PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002127"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002128Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002129
Barry Warsaw53699e91996-12-10 23:23:01 +00002130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002131posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002132{
Victor Stinner8c62be82010-05-06 00:08:46 +00002133 PyObject *opath;
2134 char *path;
2135 long uid, gid;
2136 int res;
2137 if (!PyArg_ParseTuple(args, "O&ll:chown",
2138 PyUnicode_FSConverter, &opath,
2139 &uid, &gid))
2140 return NULL;
2141 path = PyBytes_AsString(opath);
2142 Py_BEGIN_ALLOW_THREADS
2143 res = chown(path, (uid_t) uid, (gid_t) gid);
2144 Py_END_ALLOW_THREADS
2145 if (res < 0)
2146 return posix_error_with_allocated_filename(opath);
2147 Py_DECREF(opath);
2148 Py_INCREF(Py_None);
2149 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002150}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002151#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002152
Christian Heimes4e30a842007-11-30 22:12:06 +00002153#ifdef HAVE_FCHOWN
2154PyDoc_STRVAR(posix_fchown__doc__,
2155"fchown(fd, uid, gid)\n\n\
2156Change the owner and group id of the file given by file descriptor\n\
2157fd to the numeric uid and gid.");
2158
2159static PyObject *
2160posix_fchown(PyObject *self, PyObject *args)
2161{
Victor Stinner8c62be82010-05-06 00:08:46 +00002162 int fd;
2163 long uid, gid;
2164 int res;
2165 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2166 return NULL;
2167 Py_BEGIN_ALLOW_THREADS
2168 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2169 Py_END_ALLOW_THREADS
2170 if (res < 0)
2171 return posix_error();
2172 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002173}
2174#endif /* HAVE_FCHOWN */
2175
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002176#ifdef HAVE_LCHOWN
2177PyDoc_STRVAR(posix_lchown__doc__,
2178"lchown(path, uid, gid)\n\n\
2179Change the owner and group id of path to the numeric uid and gid.\n\
2180This function will not follow symbolic links.");
2181
2182static PyObject *
2183posix_lchown(PyObject *self, PyObject *args)
2184{
Victor Stinner8c62be82010-05-06 00:08:46 +00002185 PyObject *opath;
2186 char *path;
2187 long uid, gid;
2188 int res;
2189 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2190 PyUnicode_FSConverter, &opath,
2191 &uid, &gid))
2192 return NULL;
2193 path = PyBytes_AsString(opath);
2194 Py_BEGIN_ALLOW_THREADS
2195 res = lchown(path, (uid_t) uid, (gid_t) gid);
2196 Py_END_ALLOW_THREADS
2197 if (res < 0)
2198 return posix_error_with_allocated_filename(opath);
2199 Py_DECREF(opath);
2200 Py_INCREF(Py_None);
2201 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002202}
2203#endif /* HAVE_LCHOWN */
2204
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002205
Guido van Rossum36bc6801995-06-14 22:54:23 +00002206#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002207static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002208posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002209{
Victor Stinner8c62be82010-05-06 00:08:46 +00002210 char buf[1026];
2211 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002212
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002213#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002214 if (!use_bytes) {
2215 wchar_t wbuf[1026];
2216 wchar_t *wbuf2 = wbuf;
2217 PyObject *resobj;
2218 DWORD len;
2219 Py_BEGIN_ALLOW_THREADS
2220 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2221 /* If the buffer is large enough, len does not include the
2222 terminating \0. If the buffer is too small, len includes
2223 the space needed for the terminator. */
2224 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2225 wbuf2 = malloc(len * sizeof(wchar_t));
2226 if (wbuf2)
2227 len = GetCurrentDirectoryW(len, wbuf2);
2228 }
2229 Py_END_ALLOW_THREADS
2230 if (!wbuf2) {
2231 PyErr_NoMemory();
2232 return NULL;
2233 }
2234 if (!len) {
2235 if (wbuf2 != wbuf) free(wbuf2);
2236 return win32_error("getcwdu", NULL);
2237 }
2238 resobj = PyUnicode_FromWideChar(wbuf2, len);
2239 if (wbuf2 != wbuf) free(wbuf2);
2240 return resobj;
2241 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002242#endif
2243
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002245#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002247#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002248 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002249#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002250 Py_END_ALLOW_THREADS
2251 if (res == NULL)
2252 return posix_error();
2253 if (use_bytes)
2254 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002255 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002256}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002257
2258PyDoc_STRVAR(posix_getcwd__doc__,
2259"getcwd() -> path\n\n\
2260Return a unicode string representing the current working directory.");
2261
2262static PyObject *
2263posix_getcwd_unicode(PyObject *self)
2264{
2265 return posix_getcwd(0);
2266}
2267
2268PyDoc_STRVAR(posix_getcwdb__doc__,
2269"getcwdb() -> path\n\n\
2270Return a bytes string representing the current working directory.");
2271
2272static PyObject *
2273posix_getcwd_bytes(PyObject *self)
2274{
2275 return posix_getcwd(1);
2276}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002277#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279
Guido van Rossumb6775db1994-08-01 11:34:53 +00002280#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002281PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002282"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002283Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002284
Barry Warsaw53699e91996-12-10 23:23:01 +00002285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002286posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002287{
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002289}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002290#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002291
Brian Curtin1b9df392010-11-24 20:24:31 +00002292#ifdef MS_WINDOWS
2293PyDoc_STRVAR(win32_link__doc__,
2294"link(src, dst)\n\n\
2295Create a hard link to a file.");
2296
2297static PyObject *
2298win32_link(PyObject *self, PyObject *args)
2299{
2300 PyObject *osrc, *odst;
2301 char *src, *dst;
2302 BOOL rslt;
2303
Brian Curtinfc889c42010-11-28 23:59:46 +00002304 PyUnicodeObject *usrc, *udst;
2305 if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) {
2306 Py_BEGIN_ALLOW_THREADS
2307 rslt = CreateHardLinkW(PyUnicode_AS_UNICODE(udst),
2308 PyUnicode_AS_UNICODE(usrc), NULL);
2309 Py_END_ALLOW_THREADS
2310
2311 if (rslt == 0)
2312 return win32_error("link", NULL);
2313
2314 Py_RETURN_NONE;
2315 }
2316
2317 /* Narrow strings also valid. */
2318 PyErr_Clear();
2319
Brian Curtin1b9df392010-11-24 20:24:31 +00002320 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc,
2321 PyUnicode_FSConverter, &odst))
2322 return NULL;
2323
2324 src = PyBytes_AsString(osrc);
2325 dst = PyBytes_AsString(odst);
2326
2327 Py_BEGIN_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00002328 rslt = CreateHardLinkA(dst, src, NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002329 Py_END_ALLOW_THREADS
2330
Stefan Krah30b341f2010-11-27 11:44:18 +00002331 Py_DECREF(osrc);
2332 Py_DECREF(odst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002333 if (rslt == 0)
Brian Curtinfc889c42010-11-28 23:59:46 +00002334 return win32_error("link", NULL);
Brian Curtin1b9df392010-11-24 20:24:31 +00002335
2336 Py_RETURN_NONE;
2337}
2338#endif /* MS_WINDOWS */
2339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002340
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002341PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002342"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002343Return a list containing the names of the entries in the directory.\n\
2344\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002345 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002346\n\
2347The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002348entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002349
Barry Warsaw53699e91996-12-10 23:23:01 +00002350static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002351posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002352{
Victor Stinner8c62be82010-05-06 00:08:46 +00002353 /* XXX Should redo this putting the (now four) versions of opendir
2354 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002355#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002356
Victor Stinner8c62be82010-05-06 00:08:46 +00002357 PyObject *d, *v;
2358 HANDLE hFindFile;
2359 BOOL result;
2360 WIN32_FIND_DATA FileData;
2361 PyObject *opath;
2362 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2363 char *bufptr = namebuf;
2364 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002365
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002366 PyObject *po = NULL;
2367 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002368 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002369 Py_UNICODE *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002370
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002371 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002372 po_wchars = L".";
2373 len = 1;
2374 } else {
2375 po_wchars = PyUnicode_AS_UNICODE(po);
2376 len = PyUnicode_GET_SIZE(po);
2377 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002378 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002379 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2380 if (!wnamebuf) {
2381 PyErr_NoMemory();
2382 return NULL;
2383 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002384 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002385 if (len > 0) {
2386 Py_UNICODE wch = wnamebuf[len-1];
2387 if (wch != L'/' && wch != L'\\' && wch != L':')
2388 wnamebuf[len++] = L'\\';
2389 wcscpy(wnamebuf + len, L"*.*");
2390 }
2391 if ((d = PyList_New(0)) == NULL) {
2392 free(wnamebuf);
2393 return NULL;
2394 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002395 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002396 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002397 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002398 if (hFindFile == INVALID_HANDLE_VALUE) {
2399 int error = GetLastError();
2400 if (error == ERROR_FILE_NOT_FOUND) {
2401 free(wnamebuf);
2402 return d;
2403 }
2404 Py_DECREF(d);
2405 win32_error_unicode("FindFirstFileW", wnamebuf);
2406 free(wnamebuf);
2407 return NULL;
2408 }
2409 do {
2410 /* Skip over . and .. */
2411 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2412 wcscmp(wFileData.cFileName, L"..") != 0) {
2413 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2414 if (v == NULL) {
2415 Py_DECREF(d);
2416 d = NULL;
2417 break;
2418 }
2419 if (PyList_Append(d, v) != 0) {
2420 Py_DECREF(v);
2421 Py_DECREF(d);
2422 d = NULL;
2423 break;
2424 }
2425 Py_DECREF(v);
2426 }
2427 Py_BEGIN_ALLOW_THREADS
2428 result = FindNextFileW(hFindFile, &wFileData);
2429 Py_END_ALLOW_THREADS
2430 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2431 it got to the end of the directory. */
2432 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2433 Py_DECREF(d);
2434 win32_error_unicode("FindNextFileW", wnamebuf);
2435 FindClose(hFindFile);
2436 free(wnamebuf);
2437 return NULL;
2438 }
2439 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002440
Victor Stinner8c62be82010-05-06 00:08:46 +00002441 if (FindClose(hFindFile) == FALSE) {
2442 Py_DECREF(d);
2443 win32_error_unicode("FindClose", wnamebuf);
2444 free(wnamebuf);
2445 return NULL;
2446 }
2447 free(wnamebuf);
2448 return d;
2449 }
2450 /* Drop the argument parsing error as narrow strings
2451 are also valid. */
2452 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002453
Victor Stinner8c62be82010-05-06 00:08:46 +00002454 if (!PyArg_ParseTuple(args, "O&:listdir",
2455 PyUnicode_FSConverter, &opath))
2456 return NULL;
2457 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2458 PyErr_SetString(PyExc_ValueError, "path too long");
2459 Py_DECREF(opath);
2460 return NULL;
2461 }
2462 strcpy(namebuf, PyBytes_AsString(opath));
2463 len = PyObject_Size(opath);
Stefan Krah2a7feee2010-11-27 22:06:49 +00002464 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002465 if (len > 0) {
2466 char ch = namebuf[len-1];
2467 if (ch != SEP && ch != ALTSEP && ch != ':')
2468 namebuf[len++] = '/';
2469 strcpy(namebuf + len, "*.*");
2470 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002471
Victor Stinner8c62be82010-05-06 00:08:46 +00002472 if ((d = PyList_New(0)) == NULL)
2473 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002474
Antoine Pitroub73caab2010-08-09 23:39:31 +00002475 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002476 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002477 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002478 if (hFindFile == INVALID_HANDLE_VALUE) {
2479 int error = GetLastError();
2480 if (error == ERROR_FILE_NOT_FOUND)
2481 return d;
2482 Py_DECREF(d);
2483 return win32_error("FindFirstFile", namebuf);
2484 }
2485 do {
2486 /* Skip over . and .. */
2487 if (strcmp(FileData.cFileName, ".") != 0 &&
2488 strcmp(FileData.cFileName, "..") != 0) {
2489 v = PyBytes_FromString(FileData.cFileName);
2490 if (v == NULL) {
2491 Py_DECREF(d);
2492 d = NULL;
2493 break;
2494 }
2495 if (PyList_Append(d, v) != 0) {
2496 Py_DECREF(v);
2497 Py_DECREF(d);
2498 d = NULL;
2499 break;
2500 }
2501 Py_DECREF(v);
2502 }
2503 Py_BEGIN_ALLOW_THREADS
2504 result = FindNextFile(hFindFile, &FileData);
2505 Py_END_ALLOW_THREADS
2506 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2507 it got to the end of the directory. */
2508 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2509 Py_DECREF(d);
2510 win32_error("FindNextFile", namebuf);
2511 FindClose(hFindFile);
2512 return NULL;
2513 }
2514 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002515
Victor Stinner8c62be82010-05-06 00:08:46 +00002516 if (FindClose(hFindFile) == FALSE) {
2517 Py_DECREF(d);
2518 return win32_error("FindClose", namebuf);
2519 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002520
Victor Stinner8c62be82010-05-06 00:08:46 +00002521 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002522
Tim Peters0bb44a42000-09-15 07:44:49 +00002523#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002524
2525#ifndef MAX_PATH
2526#define MAX_PATH CCHMAXPATH
2527#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002528 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002529 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002530 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002531 PyObject *d, *v;
2532 char namebuf[MAX_PATH+5];
2533 HDIR hdir = 1;
2534 ULONG srchcnt = 1;
2535 FILEFINDBUF3 ep;
2536 APIRET rc;
2537
Victor Stinner8c62be82010-05-06 00:08:46 +00002538 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002539 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002540 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002541 name = PyBytes_AsString(oname);
2542 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002543 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002544 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002545 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002546 return NULL;
2547 }
2548 strcpy(namebuf, name);
2549 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002550 if (*pt == ALTSEP)
2551 *pt = SEP;
2552 if (namebuf[len-1] != SEP)
2553 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002554 strcpy(namebuf + len, "*.*");
2555
Neal Norwitz6c913782007-10-14 03:23:09 +00002556 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002557 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002558 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002559 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002560
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002561 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2562 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002563 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002564 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2565 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2566 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002567
2568 if (rc != NO_ERROR) {
2569 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002570 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002571 }
2572
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002573 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002574 do {
2575 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002576 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002577 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002578
2579 strcpy(namebuf, ep.achName);
2580
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002581 /* Leave Case of Name Alone -- In Native Form */
2582 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002583
Christian Heimes72b710a2008-05-26 13:28:38 +00002584 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002585 if (v == NULL) {
2586 Py_DECREF(d);
2587 d = NULL;
2588 break;
2589 }
2590 if (PyList_Append(d, v) != 0) {
2591 Py_DECREF(v);
2592 Py_DECREF(d);
2593 d = NULL;
2594 break;
2595 }
2596 Py_DECREF(v);
2597 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2598 }
2599
Victor Stinnerdcb24032010-04-22 12:08:36 +00002600 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002601 return d;
2602#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002603 PyObject *oname;
2604 char *name;
2605 PyObject *d, *v;
2606 DIR *dirp;
2607 struct dirent *ep;
2608 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002609
Victor Stinner8c62be82010-05-06 00:08:46 +00002610 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002611 /* v is never read, so it does not need to be initialized yet. */
2612 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002613 arg_is_unicode = 0;
2614 PyErr_Clear();
2615 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002616 oname = NULL;
2617 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002618 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002619 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002620 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002621 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002622 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002623 Py_BEGIN_ALLOW_THREADS
2624 dirp = opendir(name);
2625 Py_END_ALLOW_THREADS
2626 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002627 return posix_error_with_allocated_filename(oname);
2628 }
2629 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002630 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002631 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002632 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002633 Py_DECREF(oname);
2634 return NULL;
2635 }
2636 for (;;) {
2637 errno = 0;
2638 Py_BEGIN_ALLOW_THREADS
2639 ep = readdir(dirp);
2640 Py_END_ALLOW_THREADS
2641 if (ep == NULL) {
2642 if (errno == 0) {
2643 break;
2644 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002645 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002646 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002647 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002648 Py_DECREF(d);
2649 return posix_error_with_allocated_filename(oname);
2650 }
2651 }
2652 if (ep->d_name[0] == '.' &&
2653 (NAMLEN(ep) == 1 ||
2654 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2655 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002656 if (arg_is_unicode)
2657 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2658 else
2659 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002661 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002662 break;
2663 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 if (PyList_Append(d, v) != 0) {
2665 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002666 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002667 break;
2668 }
2669 Py_DECREF(v);
2670 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002671 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002673 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002674 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002675
Victor Stinner8c62be82010-05-06 00:08:46 +00002676 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002677
Tim Peters0bb44a42000-09-15 07:44:49 +00002678#endif /* which OS */
2679} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002680
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002681#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002682/* A helper function for abspath on win32 */
2683static PyObject *
2684posix__getfullpathname(PyObject *self, PyObject *args)
2685{
Victor Stinner8c62be82010-05-06 00:08:46 +00002686 PyObject *opath;
2687 char *path;
2688 char outbuf[MAX_PATH*2];
2689 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002690#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002691 PyUnicodeObject *po;
2692 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2693 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2694 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2695 Py_UNICODE *wtemp;
2696 DWORD result;
2697 PyObject *v;
2698 result = GetFullPathNameW(wpath,
2699 sizeof(woutbuf)/sizeof(woutbuf[0]),
2700 woutbuf, &wtemp);
2701 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2702 woutbufp = malloc(result * sizeof(Py_UNICODE));
2703 if (!woutbufp)
2704 return PyErr_NoMemory();
2705 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2706 }
2707 if (result)
2708 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2709 else
2710 v = win32_error_unicode("GetFullPathNameW", wpath);
2711 if (woutbufp != woutbuf)
2712 free(woutbufp);
2713 return v;
2714 }
2715 /* Drop the argument parsing error as narrow strings
2716 are also valid. */
2717 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002718
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002719#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002720 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2721 PyUnicode_FSConverter, &opath))
2722 return NULL;
2723 path = PyBytes_AsString(opath);
2724 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2725 outbuf, &temp)) {
2726 win32_error("GetFullPathName", path);
2727 Py_DECREF(opath);
2728 return NULL;
2729 }
2730 Py_DECREF(opath);
2731 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2732 return PyUnicode_Decode(outbuf, strlen(outbuf),
2733 Py_FileSystemDefaultEncoding, NULL);
2734 }
2735 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002736} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002737
Brian Curtinf5e76d02010-11-24 13:14:05 +00002738/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
2739static int has_GetFinalPathNameByHandle = 0;
2740static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
2741 DWORD);
2742static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
2743 DWORD);
2744static int
2745check_GetFinalPathNameByHandle()
2746{
2747 HINSTANCE hKernel32;
2748 /* only recheck */
2749 if (!has_GetFinalPathNameByHandle)
2750 {
2751 hKernel32 = GetModuleHandle("KERNEL32");
2752 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
2753 "GetFinalPathNameByHandleA");
2754 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
2755 "GetFinalPathNameByHandleW");
2756 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
2757 Py_GetFinalPathNameByHandleW;
2758 }
2759 return has_GetFinalPathNameByHandle;
2760}
2761
Brian Curtind40e6f72010-07-08 21:39:08 +00002762/* A helper function for samepath on windows */
2763static PyObject *
2764posix__getfinalpathname(PyObject *self, PyObject *args)
2765{
2766 HANDLE hFile;
2767 int buf_size;
2768 wchar_t *target_path;
2769 int result_length;
2770 PyObject *result;
2771 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002772
Brian Curtin94622b02010-09-24 00:03:39 +00002773 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002774 return NULL;
2775 }
2776
2777 if(!check_GetFinalPathNameByHandle()) {
2778 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2779 NotImplementedError. */
2780 return PyErr_Format(PyExc_NotImplementedError,
2781 "GetFinalPathNameByHandle not available on this platform");
2782 }
2783
2784 hFile = CreateFileW(
2785 path,
2786 0, /* desired access */
2787 0, /* share mode */
2788 NULL, /* security attributes */
2789 OPEN_EXISTING,
2790 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2791 FILE_FLAG_BACKUP_SEMANTICS,
2792 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002793
Brian Curtind40e6f72010-07-08 21:39:08 +00002794 if(hFile == INVALID_HANDLE_VALUE) {
2795 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002796 return PyErr_Format(PyExc_RuntimeError,
2797 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002798 }
2799
2800 /* We have a good handle to the target, use it to determine the
2801 target path name. */
2802 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2803
2804 if(!buf_size)
2805 return win32_error_unicode("GetFinalPathNameByHandle", path);
2806
2807 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2808 if(!target_path)
2809 return PyErr_NoMemory();
2810
2811 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2812 buf_size, VOLUME_NAME_DOS);
2813 if(!result_length)
2814 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2815
2816 if(!CloseHandle(hFile))
2817 return win32_error_unicode("GetFinalPathNameByHandle", path);
2818
2819 target_path[result_length] = 0;
2820 result = PyUnicode_FromUnicode(target_path, result_length);
2821 free(target_path);
2822 return result;
2823
2824} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002825
2826static PyObject *
2827posix__getfileinformation(PyObject *self, PyObject *args)
2828{
2829 HANDLE hFile;
2830 BY_HANDLE_FILE_INFORMATION info;
2831 int fd;
2832
2833 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2834 return NULL;
2835
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00002836 if (!_PyVerify_fd(fd))
2837 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00002838
2839 hFile = (HANDLE)_get_osfhandle(fd);
2840 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00002841 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00002842
2843 if (!GetFileInformationByHandle(hFile, &info))
2844 return win32_error("_getfileinformation", NULL);
2845
2846 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2847 info.nFileIndexHigh,
2848 info.nFileIndexLow);
2849}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002850#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002851
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002852PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002853"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002854Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855
Barry Warsaw53699e91996-12-10 23:23:01 +00002856static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002857posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002858{
Victor Stinner8c62be82010-05-06 00:08:46 +00002859 int res;
2860 PyObject *opath;
2861 char *path;
2862 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002863
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002864#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002865 PyUnicodeObject *po;
2866 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2867 Py_BEGIN_ALLOW_THREADS
2868 /* PyUnicode_AS_UNICODE OK without thread lock as
2869 it is a simple dereference. */
2870 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2871 Py_END_ALLOW_THREADS
2872 if (!res)
2873 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2874 Py_INCREF(Py_None);
2875 return Py_None;
2876 }
2877 /* Drop the argument parsing error as narrow strings
2878 are also valid. */
2879 PyErr_Clear();
2880 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2881 PyUnicode_FSConverter, &opath, &mode))
2882 return NULL;
2883 path = PyBytes_AsString(opath);
2884 Py_BEGIN_ALLOW_THREADS
2885 /* PyUnicode_AS_UNICODE OK without thread lock as
2886 it is a simple dereference. */
2887 res = CreateDirectoryA(path, NULL);
2888 Py_END_ALLOW_THREADS
2889 if (!res) {
2890 win32_error("mkdir", path);
2891 Py_DECREF(opath);
2892 return NULL;
2893 }
2894 Py_DECREF(opath);
2895 Py_INCREF(Py_None);
2896 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002897#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002898
Victor Stinner8c62be82010-05-06 00:08:46 +00002899 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2900 PyUnicode_FSConverter, &opath, &mode))
2901 return NULL;
2902 path = PyBytes_AsString(opath);
2903 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002904#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002906#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002907 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002908#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002909 Py_END_ALLOW_THREADS
2910 if (res < 0)
2911 return posix_error_with_allocated_filename(opath);
2912 Py_DECREF(opath);
2913 Py_INCREF(Py_None);
2914 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002915#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002916}
2917
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002918
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002919/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2920#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002921#include <sys/resource.h>
2922#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002923
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002924
2925#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002926PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002927"nice(inc) -> new_priority\n\n\
2928Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002929
Barry Warsaw53699e91996-12-10 23:23:01 +00002930static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002931posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002932{
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002934
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2936 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002937
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 /* There are two flavours of 'nice': one that returns the new
2939 priority (as required by almost all standards out there) and the
2940 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2941 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002942
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 If we are of the nice family that returns the new priority, we
2944 need to clear errno before the call, and check if errno is filled
2945 before calling posix_error() on a returnvalue of -1, because the
2946 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002947
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 errno = 0;
2949 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002950#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002951 if (value == 0)
2952 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002953#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002954 if (value == -1 && errno != 0)
2955 /* either nice() or getpriority() returned an error */
2956 return posix_error();
2957 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002958}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002959#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002960
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002962"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002963Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002964
Barry Warsaw53699e91996-12-10 23:23:01 +00002965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002966posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002967{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002968#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 PyObject *o1, *o2;
2970 char *p1, *p2;
2971 BOOL result;
2972 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2973 goto error;
2974 if (!convert_to_unicode(&o1))
2975 goto error;
2976 if (!convert_to_unicode(&o2)) {
2977 Py_DECREF(o1);
2978 goto error;
2979 }
2980 Py_BEGIN_ALLOW_THREADS
2981 result = MoveFileW(PyUnicode_AsUnicode(o1),
2982 PyUnicode_AsUnicode(o2));
2983 Py_END_ALLOW_THREADS
2984 Py_DECREF(o1);
2985 Py_DECREF(o2);
2986 if (!result)
2987 return win32_error("rename", NULL);
2988 Py_INCREF(Py_None);
2989 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002990error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002991 PyErr_Clear();
2992 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2993 return NULL;
2994 Py_BEGIN_ALLOW_THREADS
2995 result = MoveFileA(p1, p2);
2996 Py_END_ALLOW_THREADS
2997 if (!result)
2998 return win32_error("rename", NULL);
2999 Py_INCREF(Py_None);
3000 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003001#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003002 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003003#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003004}
3005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003007PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003008"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003009Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003010
Barry Warsaw53699e91996-12-10 23:23:01 +00003011static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003012posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003013{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003014#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003016#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003017 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003018#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003019}
3020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003021
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003022PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003023"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003024Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003025
Barry Warsaw53699e91996-12-10 23:23:01 +00003026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003027posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003028{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003029#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00003030 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003031#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003032 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003033#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003034}
3035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003036
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003037#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003038PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003039"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003040Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041
Barry Warsaw53699e91996-12-10 23:23:01 +00003042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003043posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003044{
Victor Stinner8c62be82010-05-06 00:08:46 +00003045 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003046#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003047 wchar_t *command;
3048 if (!PyArg_ParseTuple(args, "u:system", &command))
3049 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003050
Victor Stinner8c62be82010-05-06 00:08:46 +00003051 Py_BEGIN_ALLOW_THREADS
3052 sts = _wsystem(command);
3053 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003054#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003055 PyObject *command_obj;
3056 char *command;
3057 if (!PyArg_ParseTuple(args, "O&:system",
3058 PyUnicode_FSConverter, &command_obj))
3059 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003060
Victor Stinner8c62be82010-05-06 00:08:46 +00003061 command = PyBytes_AsString(command_obj);
3062 Py_BEGIN_ALLOW_THREADS
3063 sts = system(command);
3064 Py_END_ALLOW_THREADS
3065 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003066#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003067 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003068}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003069#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003070
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003072PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003073"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003074Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003075
Barry Warsaw53699e91996-12-10 23:23:01 +00003076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003077posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003078{
Victor Stinner8c62be82010-05-06 00:08:46 +00003079 int i;
3080 if (!PyArg_ParseTuple(args, "i:umask", &i))
3081 return NULL;
3082 i = (int)umask(i);
3083 if (i < 0)
3084 return posix_error();
3085 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003086}
3087
Brian Curtind40e6f72010-07-08 21:39:08 +00003088#ifdef MS_WINDOWS
3089
3090/* override the default DeleteFileW behavior so that directory
3091symlinks can be removed with this function, the same as with
3092Unix symlinks */
3093BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3094{
3095 WIN32_FILE_ATTRIBUTE_DATA info;
3096 WIN32_FIND_DATAW find_data;
3097 HANDLE find_data_handle;
3098 int is_directory = 0;
3099 int is_link = 0;
3100
3101 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3102 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003103
Brian Curtind40e6f72010-07-08 21:39:08 +00003104 /* Get WIN32_FIND_DATA structure for the path to determine if
3105 it is a symlink */
3106 if(is_directory &&
3107 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3108 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3109
3110 if(find_data_handle != INVALID_HANDLE_VALUE) {
3111 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3112 FindClose(find_data_handle);
3113 }
3114 }
3115 }
3116
3117 if (is_directory && is_link)
3118 return RemoveDirectoryW(lpFileName);
3119
3120 return DeleteFileW(lpFileName);
3121}
3122#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003123
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003124PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003125"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003126Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003127
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003128PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003129"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003130Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003131
Barry Warsaw53699e91996-12-10 23:23:01 +00003132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003133posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003134{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003135#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003136 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3137 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003138#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003139 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003140#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003141}
3142
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003143
Guido van Rossumb6775db1994-08-01 11:34:53 +00003144#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003145PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003146"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003147Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003148
Barry Warsaw53699e91996-12-10 23:23:01 +00003149static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003150posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003151{
Victor Stinner8c62be82010-05-06 00:08:46 +00003152 struct utsname u;
3153 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003154
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 Py_BEGIN_ALLOW_THREADS
3156 res = uname(&u);
3157 Py_END_ALLOW_THREADS
3158 if (res < 0)
3159 return posix_error();
3160 return Py_BuildValue("(sssss)",
3161 u.sysname,
3162 u.nodename,
3163 u.release,
3164 u.version,
3165 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003166}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003167#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003168
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003169static int
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003170extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003171{
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003172 time_t intval;
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 if (PyFloat_Check(t)) {
3174 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003175 PyObject *intobj = PyNumber_Long(t);
Victor Stinner8c62be82010-05-06 00:08:46 +00003176 if (!intobj)
3177 return -1;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003178#if SIZEOF_TIME_T > SIZEOF_LONG
3179 intval = PyLong_AsUnsignedLongLongMask(intobj);
3180#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003181 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003182#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 Py_DECREF(intobj);
3184 if (intval == -1 && PyErr_Occurred())
3185 return -1;
3186 *sec = intval;
3187 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3188 if (*usec < 0)
3189 /* If rounding gave us a negative number,
3190 truncate. */
3191 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003192 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 }
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003194#if SIZEOF_TIME_T > SIZEOF_LONG
3195 intval = PyLong_AsUnsignedLongLongMask(t);
3196#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003198#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 if (intval == -1 && PyErr_Occurred())
3200 return -1;
3201 *sec = intval;
3202 *usec = 0;
3203 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003204}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003205
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003206PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003207"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003208utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003209Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003210second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003211
Barry Warsaw53699e91996-12-10 23:23:01 +00003212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003213posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003214{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003215#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003216 PyObject *arg;
3217 PyUnicodeObject *obwpath;
3218 wchar_t *wpath = NULL;
3219 PyObject *oapath;
3220 char *apath;
3221 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003222 time_t atimesec, mtimesec;
3223 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 FILETIME atime, mtime;
3225 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003226
Victor Stinner8c62be82010-05-06 00:08:46 +00003227 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3228 wpath = PyUnicode_AS_UNICODE(obwpath);
3229 Py_BEGIN_ALLOW_THREADS
3230 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3231 NULL, OPEN_EXISTING,
3232 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3233 Py_END_ALLOW_THREADS
3234 if (hFile == INVALID_HANDLE_VALUE)
3235 return win32_error_unicode("utime", wpath);
3236 } else
3237 /* Drop the argument parsing error as narrow strings
3238 are also valid. */
3239 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003240
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 if (!wpath) {
3242 if (!PyArg_ParseTuple(args, "O&O:utime",
3243 PyUnicode_FSConverter, &oapath, &arg))
3244 return NULL;
3245 apath = PyBytes_AsString(oapath);
3246 Py_BEGIN_ALLOW_THREADS
3247 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3248 NULL, OPEN_EXISTING,
3249 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3250 Py_END_ALLOW_THREADS
3251 if (hFile == INVALID_HANDLE_VALUE) {
3252 win32_error("utime", apath);
3253 Py_DECREF(oapath);
3254 return NULL;
3255 }
3256 Py_DECREF(oapath);
3257 }
3258
3259 if (arg == Py_None) {
3260 SYSTEMTIME now;
3261 GetSystemTime(&now);
3262 if (!SystemTimeToFileTime(&now, &mtime) ||
3263 !SystemTimeToFileTime(&now, &atime)) {
3264 win32_error("utime", NULL);
3265 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003266 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 }
3268 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3269 PyErr_SetString(PyExc_TypeError,
3270 "utime() arg 2 must be a tuple (atime, mtime)");
3271 goto done;
3272 }
3273 else {
3274 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3275 &atimesec, &ausec) == -1)
3276 goto done;
3277 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3278 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3279 &mtimesec, &musec) == -1)
3280 goto done;
3281 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3282 }
3283 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3284 /* Avoid putting the file name into the error here,
3285 as that may confuse the user into believing that
3286 something is wrong with the file, when it also
3287 could be the time stamp that gives a problem. */
3288 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003289 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 }
3291 Py_INCREF(Py_None);
3292 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003293done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 CloseHandle(hFile);
3295 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003296#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003297
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 PyObject *opath;
3299 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003300 time_t atime, mtime;
3301 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003302 int res;
3303 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003304
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003305#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003306 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003307#define ATIME buf[0].tv_sec
3308#define MTIME buf[1].tv_sec
3309#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003310/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003311 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003312#define ATIME buf.actime
3313#define MTIME buf.modtime
3314#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003315#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003317#define ATIME buf[0]
3318#define MTIME buf[1]
3319#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003320#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003321
Mark Hammond817c9292003-12-03 01:22:38 +00003322
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 if (!PyArg_ParseTuple(args, "O&O:utime",
3324 PyUnicode_FSConverter, &opath, &arg))
3325 return NULL;
3326 path = PyBytes_AsString(opath);
3327 if (arg == Py_None) {
3328 /* optional time values not given */
3329 Py_BEGIN_ALLOW_THREADS
3330 res = utime(path, NULL);
3331 Py_END_ALLOW_THREADS
3332 }
3333 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3334 PyErr_SetString(PyExc_TypeError,
3335 "utime() arg 2 must be a tuple (atime, mtime)");
3336 Py_DECREF(opath);
3337 return NULL;
3338 }
3339 else {
3340 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3341 &atime, &ausec) == -1) {
3342 Py_DECREF(opath);
3343 return NULL;
3344 }
3345 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3346 &mtime, &musec) == -1) {
3347 Py_DECREF(opath);
3348 return NULL;
3349 }
3350 ATIME = atime;
3351 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003352#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003353 buf[0].tv_usec = ausec;
3354 buf[1].tv_usec = musec;
3355 Py_BEGIN_ALLOW_THREADS
3356 res = utimes(path, buf);
3357 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003358#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003359 Py_BEGIN_ALLOW_THREADS
3360 res = utime(path, UTIME_ARG);
3361 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003362#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 }
3364 if (res < 0) {
3365 return posix_error_with_allocated_filename(opath);
3366 }
3367 Py_DECREF(opath);
3368 Py_INCREF(Py_None);
3369 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003370#undef UTIME_ARG
3371#undef ATIME
3372#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003373#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003374}
3375
Guido van Rossum85e3b011991-06-03 12:42:10 +00003376
Guido van Rossum3b066191991-06-04 19:40:25 +00003377/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003378
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003379PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003380"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003381Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382
Barry Warsaw53699e91996-12-10 23:23:01 +00003383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003384posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003385{
Victor Stinner8c62be82010-05-06 00:08:46 +00003386 int sts;
3387 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3388 return NULL;
3389 _exit(sts);
3390 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003391}
3392
Martin v. Löwis114619e2002-10-07 06:44:21 +00003393#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3394static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003395free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003396{
Victor Stinner8c62be82010-05-06 00:08:46 +00003397 Py_ssize_t i;
3398 for (i = 0; i < count; i++)
3399 PyMem_Free(array[i]);
3400 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003401}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003402
Antoine Pitrou69f71142009-05-24 21:25:49 +00003403static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003404int fsconvert_strdup(PyObject *o, char**out)
3405{
Victor Stinner8c62be82010-05-06 00:08:46 +00003406 PyObject *bytes;
3407 Py_ssize_t size;
3408 if (!PyUnicode_FSConverter(o, &bytes))
3409 return 0;
3410 size = PyBytes_GET_SIZE(bytes);
3411 *out = PyMem_Malloc(size+1);
3412 if (!*out)
3413 return 0;
3414 memcpy(*out, PyBytes_AsString(bytes), size+1);
3415 Py_DECREF(bytes);
3416 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003417}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003418#endif
3419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003420
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003421#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003422PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003423"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003424Execute an executable path with arguments, replacing current process.\n\
3425\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 path: path of executable file\n\
3427 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003428
Barry Warsaw53699e91996-12-10 23:23:01 +00003429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003430posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003431{
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 PyObject *opath;
3433 char *path;
3434 PyObject *argv;
3435 char **argvlist;
3436 Py_ssize_t i, argc;
3437 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003438
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 /* execv has two arguments: (path, argv), where
3440 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003441
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 if (!PyArg_ParseTuple(args, "O&O:execv",
3443 PyUnicode_FSConverter,
3444 &opath, &argv))
3445 return NULL;
3446 path = PyBytes_AsString(opath);
3447 if (PyList_Check(argv)) {
3448 argc = PyList_Size(argv);
3449 getitem = PyList_GetItem;
3450 }
3451 else if (PyTuple_Check(argv)) {
3452 argc = PyTuple_Size(argv);
3453 getitem = PyTuple_GetItem;
3454 }
3455 else {
3456 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3457 Py_DECREF(opath);
3458 return NULL;
3459 }
3460 if (argc < 1) {
3461 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3462 Py_DECREF(opath);
3463 return NULL;
3464 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003465
Victor Stinner8c62be82010-05-06 00:08:46 +00003466 argvlist = PyMem_NEW(char *, argc+1);
3467 if (argvlist == NULL) {
3468 Py_DECREF(opath);
3469 return PyErr_NoMemory();
3470 }
3471 for (i = 0; i < argc; i++) {
3472 if (!fsconvert_strdup((*getitem)(argv, i),
3473 &argvlist[i])) {
3474 free_string_array(argvlist, i);
3475 PyErr_SetString(PyExc_TypeError,
3476 "execv() arg 2 must contain only strings");
3477 Py_DECREF(opath);
3478 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003479
Victor Stinner8c62be82010-05-06 00:08:46 +00003480 }
3481 }
3482 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003483
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003485
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003487
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 free_string_array(argvlist, argc);
3489 Py_DECREF(opath);
3490 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003491}
3492
Victor Stinner13bb71c2010-04-23 21:41:56 +00003493static char**
3494parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3495{
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 char **envlist;
3497 Py_ssize_t i, pos, envc;
3498 PyObject *keys=NULL, *vals=NULL;
3499 PyObject *key, *val, *key2, *val2;
3500 char *p, *k, *v;
3501 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003502
Victor Stinner8c62be82010-05-06 00:08:46 +00003503 i = PyMapping_Size(env);
3504 if (i < 0)
3505 return NULL;
3506 envlist = PyMem_NEW(char *, i + 1);
3507 if (envlist == NULL) {
3508 PyErr_NoMemory();
3509 return NULL;
3510 }
3511 envc = 0;
3512 keys = PyMapping_Keys(env);
3513 vals = PyMapping_Values(env);
3514 if (!keys || !vals)
3515 goto error;
3516 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3517 PyErr_Format(PyExc_TypeError,
3518 "env.keys() or env.values() is not a list");
3519 goto error;
3520 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003521
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 for (pos = 0; pos < i; pos++) {
3523 key = PyList_GetItem(keys, pos);
3524 val = PyList_GetItem(vals, pos);
3525 if (!key || !val)
3526 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003527
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 if (PyUnicode_FSConverter(key, &key2) == 0)
3529 goto error;
3530 if (PyUnicode_FSConverter(val, &val2) == 0) {
3531 Py_DECREF(key2);
3532 goto error;
3533 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003534
3535#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3537 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003538#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 k = PyBytes_AsString(key2);
3540 v = PyBytes_AsString(val2);
3541 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003542
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 p = PyMem_NEW(char, len);
3544 if (p == NULL) {
3545 PyErr_NoMemory();
3546 Py_DECREF(key2);
3547 Py_DECREF(val2);
3548 goto error;
3549 }
3550 PyOS_snprintf(p, len, "%s=%s", k, v);
3551 envlist[envc++] = p;
3552 Py_DECREF(key2);
3553 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003554#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003556#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 }
3558 Py_DECREF(vals);
3559 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003560
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 envlist[envc] = 0;
3562 *envc_ptr = envc;
3563 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003564
3565error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003566 Py_XDECREF(keys);
3567 Py_XDECREF(vals);
3568 while (--envc >= 0)
3569 PyMem_DEL(envlist[envc]);
3570 PyMem_DEL(envlist);
3571 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003572}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003574PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003575"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003576Execute a path with arguments and environment, replacing current process.\n\
3577\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 path: path of executable file\n\
3579 args: tuple or list of arguments\n\
3580 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003581
Barry Warsaw53699e91996-12-10 23:23:01 +00003582static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003583posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003584{
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 PyObject *opath;
3586 char *path;
3587 PyObject *argv, *env;
3588 char **argvlist;
3589 char **envlist;
3590 Py_ssize_t i, argc, envc;
3591 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3592 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003593
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 /* execve has three arguments: (path, argv, env), where
3595 argv is a list or tuple of strings and env is a dictionary
3596 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003597
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 if (!PyArg_ParseTuple(args, "O&OO:execve",
3599 PyUnicode_FSConverter,
3600 &opath, &argv, &env))
3601 return NULL;
3602 path = PyBytes_AsString(opath);
3603 if (PyList_Check(argv)) {
3604 argc = PyList_Size(argv);
3605 getitem = PyList_GetItem;
3606 }
3607 else if (PyTuple_Check(argv)) {
3608 argc = PyTuple_Size(argv);
3609 getitem = PyTuple_GetItem;
3610 }
3611 else {
3612 PyErr_SetString(PyExc_TypeError,
3613 "execve() arg 2 must be a tuple or list");
3614 goto fail_0;
3615 }
3616 if (!PyMapping_Check(env)) {
3617 PyErr_SetString(PyExc_TypeError,
3618 "execve() arg 3 must be a mapping object");
3619 goto fail_0;
3620 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003621
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 argvlist = PyMem_NEW(char *, argc+1);
3623 if (argvlist == NULL) {
3624 PyErr_NoMemory();
3625 goto fail_0;
3626 }
3627 for (i = 0; i < argc; i++) {
3628 if (!fsconvert_strdup((*getitem)(argv, i),
3629 &argvlist[i]))
3630 {
3631 lastarg = i;
3632 goto fail_1;
3633 }
3634 }
3635 lastarg = argc;
3636 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003637
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 envlist = parse_envlist(env, &envc);
3639 if (envlist == NULL)
3640 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003641
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003643
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003645
Victor Stinner8c62be82010-05-06 00:08:46 +00003646 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003647
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 while (--envc >= 0)
3649 PyMem_DEL(envlist[envc]);
3650 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003651 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003652 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003653 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003654 Py_DECREF(opath);
3655 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003656}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003657#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003659
Guido van Rossuma1065681999-01-25 23:20:23 +00003660#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003661PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003662"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003663Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003664\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 mode: mode of process creation\n\
3666 path: path of executable file\n\
3667 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003668
3669static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003670posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003671{
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 PyObject *opath;
3673 char *path;
3674 PyObject *argv;
3675 char **argvlist;
3676 int mode, i;
3677 Py_ssize_t argc;
3678 Py_intptr_t spawnval;
3679 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003680
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 /* spawnv has three arguments: (mode, path, argv), where
3682 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003683
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3685 PyUnicode_FSConverter,
3686 &opath, &argv))
3687 return NULL;
3688 path = PyBytes_AsString(opath);
3689 if (PyList_Check(argv)) {
3690 argc = PyList_Size(argv);
3691 getitem = PyList_GetItem;
3692 }
3693 else if (PyTuple_Check(argv)) {
3694 argc = PyTuple_Size(argv);
3695 getitem = PyTuple_GetItem;
3696 }
3697 else {
3698 PyErr_SetString(PyExc_TypeError,
3699 "spawnv() arg 2 must be a tuple or list");
3700 Py_DECREF(opath);
3701 return NULL;
3702 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003703
Victor Stinner8c62be82010-05-06 00:08:46 +00003704 argvlist = PyMem_NEW(char *, argc+1);
3705 if (argvlist == NULL) {
3706 Py_DECREF(opath);
3707 return PyErr_NoMemory();
3708 }
3709 for (i = 0; i < argc; i++) {
3710 if (!fsconvert_strdup((*getitem)(argv, i),
3711 &argvlist[i])) {
3712 free_string_array(argvlist, i);
3713 PyErr_SetString(
3714 PyExc_TypeError,
3715 "spawnv() arg 2 must contain only strings");
3716 Py_DECREF(opath);
3717 return NULL;
3718 }
3719 }
3720 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003721
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003722#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 Py_BEGIN_ALLOW_THREADS
3724 spawnval = spawnv(mode, path, argvlist);
3725 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003726#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003727 if (mode == _OLD_P_OVERLAY)
3728 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003729
Victor Stinner8c62be82010-05-06 00:08:46 +00003730 Py_BEGIN_ALLOW_THREADS
3731 spawnval = _spawnv(mode, path, argvlist);
3732 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003733#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003734
Victor Stinner8c62be82010-05-06 00:08:46 +00003735 free_string_array(argvlist, argc);
3736 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003737
Victor Stinner8c62be82010-05-06 00:08:46 +00003738 if (spawnval == -1)
3739 return posix_error();
3740 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003741#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003742 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003743#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003744 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003745#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003746}
3747
3748
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003749PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003750"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003751Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003752\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 mode: mode of process creation\n\
3754 path: path of executable file\n\
3755 args: tuple or list of arguments\n\
3756 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003757
3758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003759posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003760{
Victor Stinner8c62be82010-05-06 00:08:46 +00003761 PyObject *opath;
3762 char *path;
3763 PyObject *argv, *env;
3764 char **argvlist;
3765 char **envlist;
3766 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003767 int mode;
3768 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 Py_intptr_t spawnval;
3770 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3771 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003772
Victor Stinner8c62be82010-05-06 00:08:46 +00003773 /* spawnve has four arguments: (mode, path, argv, env), where
3774 argv is a list or tuple of strings and env is a dictionary
3775 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003776
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3778 PyUnicode_FSConverter,
3779 &opath, &argv, &env))
3780 return NULL;
3781 path = PyBytes_AsString(opath);
3782 if (PyList_Check(argv)) {
3783 argc = PyList_Size(argv);
3784 getitem = PyList_GetItem;
3785 }
3786 else if (PyTuple_Check(argv)) {
3787 argc = PyTuple_Size(argv);
3788 getitem = PyTuple_GetItem;
3789 }
3790 else {
3791 PyErr_SetString(PyExc_TypeError,
3792 "spawnve() arg 2 must be a tuple or list");
3793 goto fail_0;
3794 }
3795 if (!PyMapping_Check(env)) {
3796 PyErr_SetString(PyExc_TypeError,
3797 "spawnve() arg 3 must be a mapping object");
3798 goto fail_0;
3799 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003800
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 argvlist = PyMem_NEW(char *, argc+1);
3802 if (argvlist == NULL) {
3803 PyErr_NoMemory();
3804 goto fail_0;
3805 }
3806 for (i = 0; i < argc; i++) {
3807 if (!fsconvert_strdup((*getitem)(argv, i),
3808 &argvlist[i]))
3809 {
3810 lastarg = i;
3811 goto fail_1;
3812 }
3813 }
3814 lastarg = argc;
3815 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003816
Victor Stinner8c62be82010-05-06 00:08:46 +00003817 envlist = parse_envlist(env, &envc);
3818 if (envlist == NULL)
3819 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003820
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003821#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003822 Py_BEGIN_ALLOW_THREADS
3823 spawnval = spawnve(mode, path, argvlist, envlist);
3824 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003825#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003826 if (mode == _OLD_P_OVERLAY)
3827 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003828
Victor Stinner8c62be82010-05-06 00:08:46 +00003829 Py_BEGIN_ALLOW_THREADS
3830 spawnval = _spawnve(mode, path, argvlist, envlist);
3831 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003832#endif
Tim Peters25059d32001-12-07 20:35:43 +00003833
Victor Stinner8c62be82010-05-06 00:08:46 +00003834 if (spawnval == -1)
3835 (void) posix_error();
3836 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003837#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003838 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003839#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003841#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003842
Victor Stinner8c62be82010-05-06 00:08:46 +00003843 while (--envc >= 0)
3844 PyMem_DEL(envlist[envc]);
3845 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003846 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003847 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003848 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003849 Py_DECREF(opath);
3850 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003851}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003852
3853/* OS/2 supports spawnvp & spawnvpe natively */
3854#if defined(PYOS_OS2)
3855PyDoc_STRVAR(posix_spawnvp__doc__,
3856"spawnvp(mode, file, args)\n\n\
3857Execute the program 'file' in a new process, using the environment\n\
3858search path to find the file.\n\
3859\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003860 mode: mode of process creation\n\
3861 file: executable file name\n\
3862 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003863
3864static PyObject *
3865posix_spawnvp(PyObject *self, PyObject *args)
3866{
Victor Stinner8c62be82010-05-06 00:08:46 +00003867 PyObject *opath;
3868 char *path;
3869 PyObject *argv;
3870 char **argvlist;
3871 int mode, i, argc;
3872 Py_intptr_t spawnval;
3873 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003874
Victor Stinner8c62be82010-05-06 00:08:46 +00003875 /* spawnvp has three arguments: (mode, path, argv), where
3876 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003877
Victor Stinner8c62be82010-05-06 00:08:46 +00003878 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3879 PyUnicode_FSConverter,
3880 &opath, &argv))
3881 return NULL;
3882 path = PyBytes_AsString(opath);
3883 if (PyList_Check(argv)) {
3884 argc = PyList_Size(argv);
3885 getitem = PyList_GetItem;
3886 }
3887 else if (PyTuple_Check(argv)) {
3888 argc = PyTuple_Size(argv);
3889 getitem = PyTuple_GetItem;
3890 }
3891 else {
3892 PyErr_SetString(PyExc_TypeError,
3893 "spawnvp() arg 2 must be a tuple or list");
3894 Py_DECREF(opath);
3895 return NULL;
3896 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003897
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 argvlist = PyMem_NEW(char *, argc+1);
3899 if (argvlist == NULL) {
3900 Py_DECREF(opath);
3901 return PyErr_NoMemory();
3902 }
3903 for (i = 0; i < argc; i++) {
3904 if (!fsconvert_strdup((*getitem)(argv, i),
3905 &argvlist[i])) {
3906 free_string_array(argvlist, i);
3907 PyErr_SetString(
3908 PyExc_TypeError,
3909 "spawnvp() arg 2 must contain only strings");
3910 Py_DECREF(opath);
3911 return NULL;
3912 }
3913 }
3914 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003915
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003917#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003919#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003920 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003922 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003923
Victor Stinner8c62be82010-05-06 00:08:46 +00003924 free_string_array(argvlist, argc);
3925 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003926
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 if (spawnval == -1)
3928 return posix_error();
3929 else
3930 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003931}
3932
3933
3934PyDoc_STRVAR(posix_spawnvpe__doc__,
3935"spawnvpe(mode, file, args, env)\n\n\
3936Execute the program 'file' in a new process, using the environment\n\
3937search path to find the file.\n\
3938\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003939 mode: mode of process creation\n\
3940 file: executable file name\n\
3941 args: tuple or list of arguments\n\
3942 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003943
3944static PyObject *
3945posix_spawnvpe(PyObject *self, PyObject *args)
3946{
Victor Stinner8c62be82010-05-06 00:08:46 +00003947 PyObject *opath
3948 char *path;
3949 PyObject *argv, *env;
3950 char **argvlist;
3951 char **envlist;
3952 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003953 int mode;
3954 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003955 Py_intptr_t spawnval;
3956 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3957 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003958
Victor Stinner8c62be82010-05-06 00:08:46 +00003959 /* spawnvpe has four arguments: (mode, path, argv, env), where
3960 argv is a list or tuple of strings and env is a dictionary
3961 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003962
Victor Stinner8c62be82010-05-06 00:08:46 +00003963 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3964 PyUnicode_FSConverter,
3965 &opath, &argv, &env))
3966 return NULL;
3967 path = PyBytes_AsString(opath);
3968 if (PyList_Check(argv)) {
3969 argc = PyList_Size(argv);
3970 getitem = PyList_GetItem;
3971 }
3972 else if (PyTuple_Check(argv)) {
3973 argc = PyTuple_Size(argv);
3974 getitem = PyTuple_GetItem;
3975 }
3976 else {
3977 PyErr_SetString(PyExc_TypeError,
3978 "spawnvpe() arg 2 must be a tuple or list");
3979 goto fail_0;
3980 }
3981 if (!PyMapping_Check(env)) {
3982 PyErr_SetString(PyExc_TypeError,
3983 "spawnvpe() arg 3 must be a mapping object");
3984 goto fail_0;
3985 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003986
Victor Stinner8c62be82010-05-06 00:08:46 +00003987 argvlist = PyMem_NEW(char *, argc+1);
3988 if (argvlist == NULL) {
3989 PyErr_NoMemory();
3990 goto fail_0;
3991 }
3992 for (i = 0; i < argc; i++) {
3993 if (!fsconvert_strdup((*getitem)(argv, i),
3994 &argvlist[i]))
3995 {
3996 lastarg = i;
3997 goto fail_1;
3998 }
3999 }
4000 lastarg = argc;
4001 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004002
Victor Stinner8c62be82010-05-06 00:08:46 +00004003 envlist = parse_envlist(env, &envc);
4004 if (envlist == NULL)
4005 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004006
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004008#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004010#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004011 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004012#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004013 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004014
Victor Stinner8c62be82010-05-06 00:08:46 +00004015 if (spawnval == -1)
4016 (void) posix_error();
4017 else
4018 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004019
Victor Stinner8c62be82010-05-06 00:08:46 +00004020 while (--envc >= 0)
4021 PyMem_DEL(envlist[envc]);
4022 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004023 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004025 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 Py_DECREF(opath);
4027 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004028}
4029#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004030#endif /* HAVE_SPAWNV */
4031
4032
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004033#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004034PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004035"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004036Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4037\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004038Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004039
4040static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004041posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004042{
Victor Stinner8c62be82010-05-06 00:08:46 +00004043 pid_t pid;
4044 int result = 0;
4045 _PyImport_AcquireLock();
4046 pid = fork1();
4047 if (pid == 0) {
4048 /* child: this clobbers and resets the import lock. */
4049 PyOS_AfterFork();
4050 } else {
4051 /* parent: release the import lock. */
4052 result = _PyImport_ReleaseLock();
4053 }
4054 if (pid == -1)
4055 return posix_error();
4056 if (result < 0) {
4057 /* Don't clobber the OSError if the fork failed. */
4058 PyErr_SetString(PyExc_RuntimeError,
4059 "not holding the import lock");
4060 return NULL;
4061 }
4062 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004063}
4064#endif
4065
4066
Guido van Rossumad0ee831995-03-01 10:34:45 +00004067#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004068PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004069"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004070Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004071Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004072
Barry Warsaw53699e91996-12-10 23:23:01 +00004073static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004074posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004075{
Victor Stinner8c62be82010-05-06 00:08:46 +00004076 pid_t pid;
4077 int result = 0;
4078 _PyImport_AcquireLock();
4079 pid = fork();
4080 if (pid == 0) {
4081 /* child: this clobbers and resets the import lock. */
4082 PyOS_AfterFork();
4083 } else {
4084 /* parent: release the import lock. */
4085 result = _PyImport_ReleaseLock();
4086 }
4087 if (pid == -1)
4088 return posix_error();
4089 if (result < 0) {
4090 /* Don't clobber the OSError if the fork failed. */
4091 PyErr_SetString(PyExc_RuntimeError,
4092 "not holding the import lock");
4093 return NULL;
4094 }
4095 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004096}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004097#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004098
Neal Norwitzb59798b2003-03-21 01:43:31 +00004099/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00004100/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
4101#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00004102#define DEV_PTY_FILE "/dev/ptc"
4103#define HAVE_DEV_PTMX
4104#else
4105#define DEV_PTY_FILE "/dev/ptmx"
4106#endif
4107
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004108#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004109#ifdef HAVE_PTY_H
4110#include <pty.h>
4111#else
4112#ifdef HAVE_LIBUTIL_H
4113#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004114#else
4115#ifdef HAVE_UTIL_H
4116#include <util.h>
4117#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004118#endif /* HAVE_LIBUTIL_H */
4119#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004120#ifdef HAVE_STROPTS_H
4121#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004122#endif
4123#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004124
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004125#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004126PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004127"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004128Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004129
4130static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004131posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004132{
Victor Stinner8c62be82010-05-06 00:08:46 +00004133 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004134#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004135 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004136#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004137#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004138 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004139#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004140 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004141#endif
4142#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004143
Thomas Wouters70c21a12000-07-14 14:28:33 +00004144#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004145 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4146 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004147#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004148 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4149 if (slave_name == NULL)
4150 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004151
Victor Stinner8c62be82010-05-06 00:08:46 +00004152 slave_fd = open(slave_name, O_RDWR);
4153 if (slave_fd < 0)
4154 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004155#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4157 if (master_fd < 0)
4158 return posix_error();
4159 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4160 /* change permission of slave */
4161 if (grantpt(master_fd) < 0) {
4162 PyOS_setsig(SIGCHLD, sig_saved);
4163 return posix_error();
4164 }
4165 /* unlock slave */
4166 if (unlockpt(master_fd) < 0) {
4167 PyOS_setsig(SIGCHLD, sig_saved);
4168 return posix_error();
4169 }
4170 PyOS_setsig(SIGCHLD, sig_saved);
4171 slave_name = ptsname(master_fd); /* get name of slave */
4172 if (slave_name == NULL)
4173 return posix_error();
4174 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4175 if (slave_fd < 0)
4176 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004177#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4179 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004180#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004181 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004182#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004183#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004184#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004185
Victor Stinner8c62be82010-05-06 00:08:46 +00004186 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004187
Fred Drake8cef4cf2000-06-28 16:40:38 +00004188}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004189#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004190
4191#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004192PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004193"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004194Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4195Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004196To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004197
4198static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004199posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004200{
Victor Stinner8c62be82010-05-06 00:08:46 +00004201 int master_fd = -1, result = 0;
4202 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004203
Victor Stinner8c62be82010-05-06 00:08:46 +00004204 _PyImport_AcquireLock();
4205 pid = forkpty(&master_fd, NULL, NULL, NULL);
4206 if (pid == 0) {
4207 /* child: this clobbers and resets the import lock. */
4208 PyOS_AfterFork();
4209 } else {
4210 /* parent: release the import lock. */
4211 result = _PyImport_ReleaseLock();
4212 }
4213 if (pid == -1)
4214 return posix_error();
4215 if (result < 0) {
4216 /* Don't clobber the OSError if the fork failed. */
4217 PyErr_SetString(PyExc_RuntimeError,
4218 "not holding the import lock");
4219 return NULL;
4220 }
4221 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004222}
4223#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004224
Guido van Rossumad0ee831995-03-01 10:34:45 +00004225#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004226PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004227"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004228Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004229
Barry Warsaw53699e91996-12-10 23:23:01 +00004230static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004231posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004232{
Victor Stinner8c62be82010-05-06 00:08:46 +00004233 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004234}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004235#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004236
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004237
Guido van Rossumad0ee831995-03-01 10:34:45 +00004238#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004239PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004240"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004241Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004242
Barry Warsaw53699e91996-12-10 23:23:01 +00004243static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004244posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004245{
Victor Stinner8c62be82010-05-06 00:08:46 +00004246 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004247}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004248#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004249
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004250
Guido van Rossumad0ee831995-03-01 10:34:45 +00004251#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004252PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004253"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004254Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004255
Barry Warsaw53699e91996-12-10 23:23:01 +00004256static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004257posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004258{
Victor Stinner8c62be82010-05-06 00:08:46 +00004259 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004260}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004261#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004262
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004263
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004264PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004265"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004266Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Barry Warsaw53699e91996-12-10 23:23:01 +00004268static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004269posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004270{
Victor Stinner8c62be82010-05-06 00:08:46 +00004271 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004272}
4273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004274
Fred Drakec9680921999-12-13 16:37:25 +00004275#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004276PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004277"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004278Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004279
4280static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004281posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004282{
4283 PyObject *result = NULL;
4284
Fred Drakec9680921999-12-13 16:37:25 +00004285#ifdef NGROUPS_MAX
4286#define MAX_GROUPS NGROUPS_MAX
4287#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004288 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004289#define MAX_GROUPS 64
4290#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004291 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004292
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004293 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004294 * This is a helper variable to store the intermediate result when
4295 * that happens.
4296 *
4297 * To keep the code readable the OSX behaviour is unconditional,
4298 * according to the POSIX spec this should be safe on all unix-y
4299 * systems.
4300 */
4301 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004302 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004303
Victor Stinner8c62be82010-05-06 00:08:46 +00004304 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004305 if (n < 0) {
4306 if (errno == EINVAL) {
4307 n = getgroups(0, NULL);
4308 if (n == -1) {
4309 return posix_error();
4310 }
4311 if (n == 0) {
4312 /* Avoid malloc(0) */
4313 alt_grouplist = grouplist;
4314 } else {
4315 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4316 if (alt_grouplist == NULL) {
4317 errno = EINVAL;
4318 return posix_error();
4319 }
4320 n = getgroups(n, alt_grouplist);
4321 if (n == -1) {
4322 PyMem_Free(alt_grouplist);
4323 return posix_error();
4324 }
4325 }
4326 } else {
4327 return posix_error();
4328 }
4329 }
4330 result = PyList_New(n);
4331 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004332 int i;
4333 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004334 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004335 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00004336 Py_DECREF(result);
4337 result = NULL;
4338 break;
Fred Drakec9680921999-12-13 16:37:25 +00004339 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004340 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004341 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004342 }
4343
4344 if (alt_grouplist != grouplist) {
4345 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004346 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004347
Fred Drakec9680921999-12-13 16:37:25 +00004348 return result;
4349}
4350#endif
4351
Antoine Pitroub7572f02009-12-02 20:46:48 +00004352#ifdef HAVE_INITGROUPS
4353PyDoc_STRVAR(posix_initgroups__doc__,
4354"initgroups(username, gid) -> None\n\n\
4355Call the system initgroups() to initialize the group access list with all of\n\
4356the groups of which the specified username is a member, plus the specified\n\
4357group id.");
4358
4359static PyObject *
4360posix_initgroups(PyObject *self, PyObject *args)
4361{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004362 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004363 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004364 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004365 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004366
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004367 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4368 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004369 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004370 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004371
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004372 res = initgroups(username, (gid_t) gid);
4373 Py_DECREF(oname);
4374 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004375 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004376
Victor Stinner8c62be82010-05-06 00:08:46 +00004377 Py_INCREF(Py_None);
4378 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004379}
4380#endif
4381
Martin v. Löwis606edc12002-06-13 21:09:11 +00004382#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004383PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004384"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004385Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004386
4387static PyObject *
4388posix_getpgid(PyObject *self, PyObject *args)
4389{
Victor Stinner8c62be82010-05-06 00:08:46 +00004390 pid_t pid, pgid;
4391 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4392 return NULL;
4393 pgid = getpgid(pid);
4394 if (pgid < 0)
4395 return posix_error();
4396 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004397}
4398#endif /* HAVE_GETPGID */
4399
4400
Guido van Rossumb6775db1994-08-01 11:34:53 +00004401#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004402PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004403"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004404Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004405
Barry Warsaw53699e91996-12-10 23:23:01 +00004406static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004407posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004408{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004409#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004410 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004411#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004412 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004413#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004414}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004415#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004417
Guido van Rossumb6775db1994-08-01 11:34:53 +00004418#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004419PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004420"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004421Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004422
Barry Warsaw53699e91996-12-10 23:23:01 +00004423static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004424posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004425{
Guido van Rossum64933891994-10-20 21:56:42 +00004426#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004427 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004428#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004429 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004430#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004431 return posix_error();
4432 Py_INCREF(Py_None);
4433 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004434}
4435
Guido van Rossumb6775db1994-08-01 11:34:53 +00004436#endif /* HAVE_SETPGRP */
4437
Guido van Rossumad0ee831995-03-01 10:34:45 +00004438#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004439
4440#ifdef MS_WINDOWS
4441#include <tlhelp32.h>
4442
4443static PyObject*
4444win32_getppid()
4445{
4446 HANDLE snapshot;
4447 pid_t mypid;
4448 PyObject* result = NULL;
4449 BOOL have_record;
4450 PROCESSENTRY32 pe;
4451
4452 mypid = getpid(); /* This function never fails */
4453
4454 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4455 if (snapshot == INVALID_HANDLE_VALUE)
4456 return PyErr_SetFromWindowsErr(GetLastError());
4457
4458 pe.dwSize = sizeof(pe);
4459 have_record = Process32First(snapshot, &pe);
4460 while (have_record) {
4461 if (mypid == (pid_t)pe.th32ProcessID) {
4462 /* We could cache the ulong value in a static variable. */
4463 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4464 break;
4465 }
4466
4467 have_record = Process32Next(snapshot, &pe);
4468 }
4469
4470 /* If our loop exits and our pid was not found (result will be NULL)
4471 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4472 * error anyway, so let's raise it. */
4473 if (!result)
4474 result = PyErr_SetFromWindowsErr(GetLastError());
4475
4476 CloseHandle(snapshot);
4477
4478 return result;
4479}
4480#endif /*MS_WINDOWS*/
4481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004482PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004483"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004484Return the parent's process id. If the parent process has already exited,\n\
4485Windows machines will still return its id; others systems will return the id\n\
4486of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004487
Barry Warsaw53699e91996-12-10 23:23:01 +00004488static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004489posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004490{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004491#ifdef MS_WINDOWS
4492 return win32_getppid();
4493#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004495#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004496}
4497#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004498
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004499
Fred Drake12c6e2d1999-12-14 21:25:03 +00004500#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004501PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004502"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004503Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004504
4505static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004506posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004507{
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004509#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004510 wchar_t user_name[UNLEN + 1];
4511 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4512
4513 if (GetUserNameW(user_name, &num_chars)) {
4514 /* num_chars is the number of unicode chars plus null terminator */
4515 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004516 }
4517 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004518 result = PyErr_SetFromWindowsErr(GetLastError());
4519#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004520 char *name;
4521 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004522
Victor Stinner8c62be82010-05-06 00:08:46 +00004523 errno = 0;
4524 name = getlogin();
4525 if (name == NULL) {
4526 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004527 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004528 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004529 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004530 }
4531 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004532 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004533 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004534#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004535 return result;
4536}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004537#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004538
Guido van Rossumad0ee831995-03-01 10:34:45 +00004539#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004540PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004541"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004542Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004543
Barry Warsaw53699e91996-12-10 23:23:01 +00004544static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004545posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004546{
Victor Stinner8c62be82010-05-06 00:08:46 +00004547 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004548}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004549#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004550
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004551
Guido van Rossumad0ee831995-03-01 10:34:45 +00004552#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004553PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004554"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004555Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004556
Barry Warsaw53699e91996-12-10 23:23:01 +00004557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004558posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004559{
Victor Stinner8c62be82010-05-06 00:08:46 +00004560 pid_t pid;
4561 int sig;
4562 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4563 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004564#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004565 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4566 APIRET rc;
4567 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004568 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004569
4570 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4571 APIRET rc;
4572 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004573 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004574
4575 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004576 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004577#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004578 if (kill(pid, sig) == -1)
4579 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004580#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004581 Py_INCREF(Py_None);
4582 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004583}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004584#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004585
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004586#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004587PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004588"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004589Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004590
4591static PyObject *
4592posix_killpg(PyObject *self, PyObject *args)
4593{
Victor Stinner8c62be82010-05-06 00:08:46 +00004594 int sig;
4595 pid_t pgid;
4596 /* XXX some man pages make the `pgid` parameter an int, others
4597 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4598 take the same type. Moreover, pid_t is always at least as wide as
4599 int (else compilation of this module fails), which is safe. */
4600 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4601 return NULL;
4602 if (killpg(pgid, sig) == -1)
4603 return posix_error();
4604 Py_INCREF(Py_None);
4605 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004606}
4607#endif
4608
Brian Curtineb24d742010-04-12 17:16:38 +00004609#ifdef MS_WINDOWS
4610PyDoc_STRVAR(win32_kill__doc__,
4611"kill(pid, sig)\n\n\
4612Kill a process with a signal.");
4613
4614static PyObject *
4615win32_kill(PyObject *self, PyObject *args)
4616{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004617 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004618 DWORD pid, sig, err;
4619 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004620
Victor Stinner8c62be82010-05-06 00:08:46 +00004621 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4622 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004623
Victor Stinner8c62be82010-05-06 00:08:46 +00004624 /* Console processes which share a common console can be sent CTRL+C or
4625 CTRL+BREAK events, provided they handle said events. */
4626 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4627 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4628 err = GetLastError();
4629 PyErr_SetFromWindowsErr(err);
4630 }
4631 else
4632 Py_RETURN_NONE;
4633 }
Brian Curtineb24d742010-04-12 17:16:38 +00004634
Victor Stinner8c62be82010-05-06 00:08:46 +00004635 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4636 attempt to open and terminate the process. */
4637 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4638 if (handle == NULL) {
4639 err = GetLastError();
4640 return PyErr_SetFromWindowsErr(err);
4641 }
Brian Curtineb24d742010-04-12 17:16:38 +00004642
Victor Stinner8c62be82010-05-06 00:08:46 +00004643 if (TerminateProcess(handle, sig) == 0) {
4644 err = GetLastError();
4645 result = PyErr_SetFromWindowsErr(err);
4646 } else {
4647 Py_INCREF(Py_None);
4648 result = Py_None;
4649 }
Brian Curtineb24d742010-04-12 17:16:38 +00004650
Victor Stinner8c62be82010-05-06 00:08:46 +00004651 CloseHandle(handle);
4652 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004653}
4654#endif /* MS_WINDOWS */
4655
Guido van Rossumc0125471996-06-28 18:55:32 +00004656#ifdef HAVE_PLOCK
4657
4658#ifdef HAVE_SYS_LOCK_H
4659#include <sys/lock.h>
4660#endif
4661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004662PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004663"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004664Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004665
Barry Warsaw53699e91996-12-10 23:23:01 +00004666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004667posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004668{
Victor Stinner8c62be82010-05-06 00:08:46 +00004669 int op;
4670 if (!PyArg_ParseTuple(args, "i:plock", &op))
4671 return NULL;
4672 if (plock(op) == -1)
4673 return posix_error();
4674 Py_INCREF(Py_None);
4675 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004676}
4677#endif
4678
Guido van Rossumb6775db1994-08-01 11:34:53 +00004679#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004680PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004681"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004682Set the current process's user id.");
4683
Barry Warsaw53699e91996-12-10 23:23:01 +00004684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004685posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004686{
Victor Stinner8c62be82010-05-06 00:08:46 +00004687 long uid_arg;
4688 uid_t uid;
4689 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4690 return NULL;
4691 uid = uid_arg;
4692 if (uid != uid_arg) {
4693 PyErr_SetString(PyExc_OverflowError, "user id too big");
4694 return NULL;
4695 }
4696 if (setuid(uid) < 0)
4697 return posix_error();
4698 Py_INCREF(Py_None);
4699 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004700}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004701#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004702
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004703
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004704#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004705PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004706"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004707Set the current process's effective user id.");
4708
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004709static PyObject *
4710posix_seteuid (PyObject *self, PyObject *args)
4711{
Victor Stinner8c62be82010-05-06 00:08:46 +00004712 long euid_arg;
4713 uid_t euid;
4714 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4715 return NULL;
4716 euid = euid_arg;
4717 if (euid != euid_arg) {
4718 PyErr_SetString(PyExc_OverflowError, "user id too big");
4719 return NULL;
4720 }
4721 if (seteuid(euid) < 0) {
4722 return posix_error();
4723 } else {
4724 Py_INCREF(Py_None);
4725 return Py_None;
4726 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004727}
4728#endif /* HAVE_SETEUID */
4729
4730#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004731PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004732"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004733Set the current process's effective group id.");
4734
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004735static PyObject *
4736posix_setegid (PyObject *self, PyObject *args)
4737{
Victor Stinner8c62be82010-05-06 00:08:46 +00004738 long egid_arg;
4739 gid_t egid;
4740 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4741 return NULL;
4742 egid = egid_arg;
4743 if (egid != egid_arg) {
4744 PyErr_SetString(PyExc_OverflowError, "group id too big");
4745 return NULL;
4746 }
4747 if (setegid(egid) < 0) {
4748 return posix_error();
4749 } else {
4750 Py_INCREF(Py_None);
4751 return Py_None;
4752 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004753}
4754#endif /* HAVE_SETEGID */
4755
4756#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004757PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004758"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004759Set the current process's real and effective user ids.");
4760
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004761static PyObject *
4762posix_setreuid (PyObject *self, PyObject *args)
4763{
Victor Stinner8c62be82010-05-06 00:08:46 +00004764 long ruid_arg, euid_arg;
4765 uid_t ruid, euid;
4766 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4767 return NULL;
4768 if (ruid_arg == -1)
4769 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4770 else
4771 ruid = ruid_arg; /* otherwise, assign from our long */
4772 if (euid_arg == -1)
4773 euid = (uid_t)-1;
4774 else
4775 euid = euid_arg;
4776 if ((euid_arg != -1 && euid != euid_arg) ||
4777 (ruid_arg != -1 && ruid != ruid_arg)) {
4778 PyErr_SetString(PyExc_OverflowError, "user id too big");
4779 return NULL;
4780 }
4781 if (setreuid(ruid, euid) < 0) {
4782 return posix_error();
4783 } else {
4784 Py_INCREF(Py_None);
4785 return Py_None;
4786 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004787}
4788#endif /* HAVE_SETREUID */
4789
4790#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004791PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004792"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004793Set the current process's real and effective group ids.");
4794
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004795static PyObject *
4796posix_setregid (PyObject *self, PyObject *args)
4797{
Victor Stinner8c62be82010-05-06 00:08:46 +00004798 long rgid_arg, egid_arg;
4799 gid_t rgid, egid;
4800 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4801 return NULL;
4802 if (rgid_arg == -1)
4803 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4804 else
4805 rgid = rgid_arg; /* otherwise, assign from our long */
4806 if (egid_arg == -1)
4807 egid = (gid_t)-1;
4808 else
4809 egid = egid_arg;
4810 if ((egid_arg != -1 && egid != egid_arg) ||
4811 (rgid_arg != -1 && rgid != rgid_arg)) {
4812 PyErr_SetString(PyExc_OverflowError, "group id too big");
4813 return NULL;
4814 }
4815 if (setregid(rgid, egid) < 0) {
4816 return posix_error();
4817 } else {
4818 Py_INCREF(Py_None);
4819 return Py_None;
4820 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004821}
4822#endif /* HAVE_SETREGID */
4823
Guido van Rossumb6775db1994-08-01 11:34:53 +00004824#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004825PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004826"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004827Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004828
Barry Warsaw53699e91996-12-10 23:23:01 +00004829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004830posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004831{
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 long gid_arg;
4833 gid_t gid;
4834 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4835 return NULL;
4836 gid = gid_arg;
4837 if (gid != gid_arg) {
4838 PyErr_SetString(PyExc_OverflowError, "group id too big");
4839 return NULL;
4840 }
4841 if (setgid(gid) < 0)
4842 return posix_error();
4843 Py_INCREF(Py_None);
4844 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004845}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004846#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004847
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004848#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004849PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004850"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004851Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004852
4853static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004854posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004855{
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 int i, len;
4857 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004858
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 if (!PySequence_Check(groups)) {
4860 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4861 return NULL;
4862 }
4863 len = PySequence_Size(groups);
4864 if (len > MAX_GROUPS) {
4865 PyErr_SetString(PyExc_ValueError, "too many groups");
4866 return NULL;
4867 }
4868 for(i = 0; i < len; i++) {
4869 PyObject *elem;
4870 elem = PySequence_GetItem(groups, i);
4871 if (!elem)
4872 return NULL;
4873 if (!PyLong_Check(elem)) {
4874 PyErr_SetString(PyExc_TypeError,
4875 "groups must be integers");
4876 Py_DECREF(elem);
4877 return NULL;
4878 } else {
4879 unsigned long x = PyLong_AsUnsignedLong(elem);
4880 if (PyErr_Occurred()) {
4881 PyErr_SetString(PyExc_TypeError,
4882 "group id too big");
4883 Py_DECREF(elem);
4884 return NULL;
4885 }
4886 grouplist[i] = x;
4887 /* read back the value to see if it fitted in gid_t */
4888 if (grouplist[i] != x) {
4889 PyErr_SetString(PyExc_TypeError,
4890 "group id too big");
4891 Py_DECREF(elem);
4892 return NULL;
4893 }
4894 }
4895 Py_DECREF(elem);
4896 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004897
Victor Stinner8c62be82010-05-06 00:08:46 +00004898 if (setgroups(len, grouplist) < 0)
4899 return posix_error();
4900 Py_INCREF(Py_None);
4901 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004902}
4903#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004904
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004905#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4906static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004907wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004908{
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 PyObject *result;
4910 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004911
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 if (pid == -1)
4913 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004914
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 if (struct_rusage == NULL) {
4916 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4917 if (m == NULL)
4918 return NULL;
4919 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4920 Py_DECREF(m);
4921 if (struct_rusage == NULL)
4922 return NULL;
4923 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004924
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4926 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4927 if (!result)
4928 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004929
4930#ifndef doubletime
4931#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4932#endif
4933
Victor Stinner8c62be82010-05-06 00:08:46 +00004934 PyStructSequence_SET_ITEM(result, 0,
4935 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4936 PyStructSequence_SET_ITEM(result, 1,
4937 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004938#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004939 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4940 SET_INT(result, 2, ru->ru_maxrss);
4941 SET_INT(result, 3, ru->ru_ixrss);
4942 SET_INT(result, 4, ru->ru_idrss);
4943 SET_INT(result, 5, ru->ru_isrss);
4944 SET_INT(result, 6, ru->ru_minflt);
4945 SET_INT(result, 7, ru->ru_majflt);
4946 SET_INT(result, 8, ru->ru_nswap);
4947 SET_INT(result, 9, ru->ru_inblock);
4948 SET_INT(result, 10, ru->ru_oublock);
4949 SET_INT(result, 11, ru->ru_msgsnd);
4950 SET_INT(result, 12, ru->ru_msgrcv);
4951 SET_INT(result, 13, ru->ru_nsignals);
4952 SET_INT(result, 14, ru->ru_nvcsw);
4953 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004954#undef SET_INT
4955
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 if (PyErr_Occurred()) {
4957 Py_DECREF(result);
4958 return NULL;
4959 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004960
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004962}
4963#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4964
4965#ifdef HAVE_WAIT3
4966PyDoc_STRVAR(posix_wait3__doc__,
4967"wait3(options) -> (pid, status, rusage)\n\n\
4968Wait for completion of a child process.");
4969
4970static PyObject *
4971posix_wait3(PyObject *self, PyObject *args)
4972{
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 pid_t pid;
4974 int options;
4975 struct rusage ru;
4976 WAIT_TYPE status;
4977 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004978
Victor Stinner8c62be82010-05-06 00:08:46 +00004979 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4980 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004981
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 Py_BEGIN_ALLOW_THREADS
4983 pid = wait3(&status, options, &ru);
4984 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004987}
4988#endif /* HAVE_WAIT3 */
4989
4990#ifdef HAVE_WAIT4
4991PyDoc_STRVAR(posix_wait4__doc__,
4992"wait4(pid, options) -> (pid, status, rusage)\n\n\
4993Wait for completion of a given child process.");
4994
4995static PyObject *
4996posix_wait4(PyObject *self, PyObject *args)
4997{
Victor Stinner8c62be82010-05-06 00:08:46 +00004998 pid_t pid;
4999 int options;
5000 struct rusage ru;
5001 WAIT_TYPE status;
5002 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005003
Victor Stinner8c62be82010-05-06 00:08:46 +00005004 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
5005 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005006
Victor Stinner8c62be82010-05-06 00:08:46 +00005007 Py_BEGIN_ALLOW_THREADS
5008 pid = wait4(pid, &status, options, &ru);
5009 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005010
Victor Stinner8c62be82010-05-06 00:08:46 +00005011 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005012}
5013#endif /* HAVE_WAIT4 */
5014
Guido van Rossumb6775db1994-08-01 11:34:53 +00005015#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005016PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005017"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005018Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005019
Barry Warsaw53699e91996-12-10 23:23:01 +00005020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005021posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005022{
Victor Stinner8c62be82010-05-06 00:08:46 +00005023 pid_t pid;
5024 int options;
5025 WAIT_TYPE status;
5026 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005027
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
5029 return NULL;
5030 Py_BEGIN_ALLOW_THREADS
5031 pid = waitpid(pid, &status, options);
5032 Py_END_ALLOW_THREADS
5033 if (pid == -1)
5034 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005035
Victor Stinner8c62be82010-05-06 00:08:46 +00005036 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005037}
5038
Tim Petersab034fa2002-02-01 11:27:43 +00005039#elif defined(HAVE_CWAIT)
5040
5041/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005042PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005043"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005044"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005045
5046static PyObject *
5047posix_waitpid(PyObject *self, PyObject *args)
5048{
Victor Stinner8c62be82010-05-06 00:08:46 +00005049 Py_intptr_t pid;
5050 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005051
Victor Stinner8c62be82010-05-06 00:08:46 +00005052 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
5053 return NULL;
5054 Py_BEGIN_ALLOW_THREADS
5055 pid = _cwait(&status, pid, options);
5056 Py_END_ALLOW_THREADS
5057 if (pid == -1)
5058 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005059
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 /* shift the status left a byte so this is more like the POSIX waitpid */
5061 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005062}
5063#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005064
Guido van Rossumad0ee831995-03-01 10:34:45 +00005065#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005066PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005067"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005068Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005069
Barry Warsaw53699e91996-12-10 23:23:01 +00005070static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005071posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005072{
Victor Stinner8c62be82010-05-06 00:08:46 +00005073 pid_t pid;
5074 WAIT_TYPE status;
5075 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005076
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 Py_BEGIN_ALLOW_THREADS
5078 pid = wait(&status);
5079 Py_END_ALLOW_THREADS
5080 if (pid == -1)
5081 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005082
Victor Stinner8c62be82010-05-06 00:08:46 +00005083 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005084}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005085#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005088PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005089"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005090Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005091
Barry Warsaw53699e91996-12-10 23:23:01 +00005092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005093posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005094{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005095#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005097#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005098#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00005099 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
5100 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005101#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005102 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005103#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005104#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005105}
5106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005107
Guido van Rossumb6775db1994-08-01 11:34:53 +00005108#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005109PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005110"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005111Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005112
Barry Warsaw53699e91996-12-10 23:23:01 +00005113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005114posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005115{
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 PyObject* v;
5117 char buf[MAXPATHLEN];
5118 PyObject *opath;
5119 char *path;
5120 int n;
5121 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005122
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 if (!PyArg_ParseTuple(args, "O&:readlink",
5124 PyUnicode_FSConverter, &opath))
5125 return NULL;
5126 path = PyBytes_AsString(opath);
5127 v = PySequence_GetItem(args, 0);
5128 if (v == NULL) {
5129 Py_DECREF(opath);
5130 return NULL;
5131 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005132
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 if (PyUnicode_Check(v)) {
5134 arg_is_unicode = 1;
5135 }
5136 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005137
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 Py_BEGIN_ALLOW_THREADS
5139 n = readlink(path, buf, (int) sizeof buf);
5140 Py_END_ALLOW_THREADS
5141 if (n < 0)
5142 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005143
Victor Stinner8c62be82010-05-06 00:08:46 +00005144 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005145 if (arg_is_unicode)
5146 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5147 else
5148 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005149}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005150#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005152
Brian Curtin52173d42010-12-02 18:29:18 +00005153#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005154PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005155"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005156Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005157
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005159posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005160{
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005162}
5163#endif /* HAVE_SYMLINK */
5164
Brian Curtind40e6f72010-07-08 21:39:08 +00005165#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5166
5167PyDoc_STRVAR(win_readlink__doc__,
5168"readlink(path) -> path\n\n\
5169Return a string representing the path to which the symbolic link points.");
5170
Brian Curtind40e6f72010-07-08 21:39:08 +00005171/* Windows readlink implementation */
5172static PyObject *
5173win_readlink(PyObject *self, PyObject *args)
5174{
5175 wchar_t *path;
5176 DWORD n_bytes_returned;
5177 DWORD io_result;
5178 PyObject *result;
5179 HANDLE reparse_point_handle;
5180
5181 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5182 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5183 wchar_t *print_name;
5184
5185 if (!PyArg_ParseTuple(args,
5186 "u:readlink",
5187 &path))
5188 return NULL;
5189
5190 /* First get a handle to the reparse point */
5191 Py_BEGIN_ALLOW_THREADS
5192 reparse_point_handle = CreateFileW(
5193 path,
5194 0,
5195 0,
5196 0,
5197 OPEN_EXISTING,
5198 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5199 0);
5200 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005201
Brian Curtind40e6f72010-07-08 21:39:08 +00005202 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5203 {
5204 return win32_error_unicode("readlink", path);
5205 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005206
Brian Curtind40e6f72010-07-08 21:39:08 +00005207 Py_BEGIN_ALLOW_THREADS
5208 /* New call DeviceIoControl to read the reparse point */
5209 io_result = DeviceIoControl(
5210 reparse_point_handle,
5211 FSCTL_GET_REPARSE_POINT,
5212 0, 0, /* in buffer */
5213 target_buffer, sizeof(target_buffer),
5214 &n_bytes_returned,
5215 0 /* we're not using OVERLAPPED_IO */
5216 );
5217 CloseHandle(reparse_point_handle);
5218 Py_END_ALLOW_THREADS
5219
5220 if (io_result==0)
5221 {
5222 return win32_error_unicode("readlink", path);
5223 }
5224
5225 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5226 {
5227 PyErr_SetString(PyExc_ValueError,
5228 "not a symbolic link");
5229 return NULL;
5230 }
Brian Curtin74e45612010-07-09 15:58:59 +00005231 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5232 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5233
5234 result = PyUnicode_FromWideChar(print_name,
5235 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005236 return result;
5237}
5238
5239#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5240
Brian Curtin52173d42010-12-02 18:29:18 +00005241#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00005242
5243/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5244static int has_CreateSymbolicLinkW = 0;
5245static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5246static int
5247check_CreateSymbolicLinkW()
5248{
5249 HINSTANCE hKernel32;
5250 /* only recheck */
5251 if (has_CreateSymbolicLinkW)
5252 return has_CreateSymbolicLinkW;
5253 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005254 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5255 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005256 if (Py_CreateSymbolicLinkW)
5257 has_CreateSymbolicLinkW = 1;
5258 return has_CreateSymbolicLinkW;
5259}
5260
5261PyDoc_STRVAR(win_symlink__doc__,
5262"symlink(src, dst, target_is_directory=False)\n\n\
5263Create a symbolic link pointing to src named dst.\n\
5264target_is_directory is required if the target is to be interpreted as\n\
5265a directory.\n\
5266This function requires Windows 6.0 or greater, and raises a\n\
5267NotImplementedError otherwise.");
5268
5269static PyObject *
5270win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5271{
5272 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5273 PyObject *src, *dest;
5274 int target_is_directory = 0;
5275 DWORD res;
5276 WIN32_FILE_ATTRIBUTE_DATA src_info;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005277
Brian Curtind40e6f72010-07-08 21:39:08 +00005278 if (!check_CreateSymbolicLinkW())
5279 {
5280 /* raise NotImplementedError */
5281 return PyErr_Format(PyExc_NotImplementedError,
5282 "CreateSymbolicLinkW not found");
5283 }
5284 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5285 kwlist, &src, &dest, &target_is_directory))
5286 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00005287
5288 if (win32_can_symlink == 0)
5289 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
5290
Brian Curtind40e6f72010-07-08 21:39:08 +00005291 if (!convert_to_unicode(&src)) { return NULL; }
5292 if (!convert_to_unicode(&dest)) {
5293 Py_DECREF(src);
5294 return NULL;
5295 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005296
Brian Curtind40e6f72010-07-08 21:39:08 +00005297 /* if src is a directory, ensure target_is_directory==1 */
5298 if(
5299 GetFileAttributesExW(
5300 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5301 ))
5302 {
5303 target_is_directory = target_is_directory ||
5304 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5305 }
5306
5307 Py_BEGIN_ALLOW_THREADS
5308 res = Py_CreateSymbolicLinkW(
5309 PyUnicode_AsUnicode(dest),
5310 PyUnicode_AsUnicode(src),
5311 target_is_directory);
5312 Py_END_ALLOW_THREADS
5313 Py_DECREF(src);
5314 Py_DECREF(dest);
5315 if (!res)
5316 {
5317 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5318 }
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005319
Brian Curtind40e6f72010-07-08 21:39:08 +00005320 Py_INCREF(Py_None);
5321 return Py_None;
5322}
Brian Curtin52173d42010-12-02 18:29:18 +00005323#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005324
5325#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005326#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5327static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005328system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005329{
5330 ULONG value = 0;
5331
5332 Py_BEGIN_ALLOW_THREADS
5333 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5334 Py_END_ALLOW_THREADS
5335
5336 return value;
5337}
5338
5339static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005340posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005341{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005342 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 return Py_BuildValue("ddddd",
5344 (double)0 /* t.tms_utime / HZ */,
5345 (double)0 /* t.tms_stime / HZ */,
5346 (double)0 /* t.tms_cutime / HZ */,
5347 (double)0 /* t.tms_cstime / HZ */,
5348 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005349}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005350#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005351#define NEED_TICKS_PER_SECOND
5352static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005353static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005354posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005355{
Victor Stinner8c62be82010-05-06 00:08:46 +00005356 struct tms t;
5357 clock_t c;
5358 errno = 0;
5359 c = times(&t);
5360 if (c == (clock_t) -1)
5361 return posix_error();
5362 return Py_BuildValue("ddddd",
5363 (double)t.tms_utime / ticks_per_second,
5364 (double)t.tms_stime / ticks_per_second,
5365 (double)t.tms_cutime / ticks_per_second,
5366 (double)t.tms_cstime / ticks_per_second,
5367 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005368}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005369#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005370#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005371
5372
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005373#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005374#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005375static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005376posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005377{
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 FILETIME create, exit, kernel, user;
5379 HANDLE hProc;
5380 hProc = GetCurrentProcess();
5381 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5382 /* The fields of a FILETIME structure are the hi and lo part
5383 of a 64-bit value expressed in 100 nanosecond units.
5384 1e7 is one second in such units; 1e-7 the inverse.
5385 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5386 */
5387 return Py_BuildValue(
5388 "ddddd",
5389 (double)(user.dwHighDateTime*429.4967296 +
5390 user.dwLowDateTime*1e-7),
5391 (double)(kernel.dwHighDateTime*429.4967296 +
5392 kernel.dwLowDateTime*1e-7),
5393 (double)0,
5394 (double)0,
5395 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005396}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005397#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005398
5399#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005400PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005401"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005402Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005403#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005405
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005406#ifdef HAVE_GETSID
5407PyDoc_STRVAR(posix_getsid__doc__,
5408"getsid(pid) -> sid\n\n\
5409Call the system call getsid().");
5410
5411static PyObject *
5412posix_getsid(PyObject *self, PyObject *args)
5413{
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 pid_t pid;
5415 int sid;
5416 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5417 return NULL;
5418 sid = getsid(pid);
5419 if (sid < 0)
5420 return posix_error();
5421 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005422}
5423#endif /* HAVE_GETSID */
5424
5425
Guido van Rossumb6775db1994-08-01 11:34:53 +00005426#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005427PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005428"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005429Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005430
Barry Warsaw53699e91996-12-10 23:23:01 +00005431static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005432posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005433{
Victor Stinner8c62be82010-05-06 00:08:46 +00005434 if (setsid() < 0)
5435 return posix_error();
5436 Py_INCREF(Py_None);
5437 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005438}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005439#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005440
Guido van Rossumb6775db1994-08-01 11:34:53 +00005441#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005442PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005443"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005445
Barry Warsaw53699e91996-12-10 23:23:01 +00005446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005447posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005448{
Victor Stinner8c62be82010-05-06 00:08:46 +00005449 pid_t pid;
5450 int pgrp;
5451 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5452 return NULL;
5453 if (setpgid(pid, pgrp) < 0)
5454 return posix_error();
5455 Py_INCREF(Py_None);
5456 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005457}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005458#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005460
Guido van Rossumb6775db1994-08-01 11:34:53 +00005461#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005462PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005463"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005464Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005465
Barry Warsaw53699e91996-12-10 23:23:01 +00005466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005467posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005468{
Victor Stinner8c62be82010-05-06 00:08:46 +00005469 int fd;
5470 pid_t pgid;
5471 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5472 return NULL;
5473 pgid = tcgetpgrp(fd);
5474 if (pgid < 0)
5475 return posix_error();
5476 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005477}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005478#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005480
Guido van Rossumb6775db1994-08-01 11:34:53 +00005481#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005482PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005483"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005485
Barry Warsaw53699e91996-12-10 23:23:01 +00005486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005487posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005488{
Victor Stinner8c62be82010-05-06 00:08:46 +00005489 int fd;
5490 pid_t pgid;
5491 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5492 return NULL;
5493 if (tcsetpgrp(fd, pgid) < 0)
5494 return posix_error();
5495 Py_INCREF(Py_None);
5496 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005497}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005498#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005499
Guido van Rossum687dd131993-05-17 08:34:16 +00005500/* Functions acting on file descriptors */
5501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005502PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005503"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005504Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005505
Barry Warsaw53699e91996-12-10 23:23:01 +00005506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005507posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005508{
Victor Stinner8c62be82010-05-06 00:08:46 +00005509 PyObject *ofile;
5510 char *file;
5511 int flag;
5512 int mode = 0777;
5513 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005514
5515#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005516 PyUnicodeObject *po;
5517 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5518 Py_BEGIN_ALLOW_THREADS
5519 /* PyUnicode_AS_UNICODE OK without thread
5520 lock as it is a simple dereference. */
5521 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5522 Py_END_ALLOW_THREADS
5523 if (fd < 0)
5524 return posix_error();
5525 return PyLong_FromLong((long)fd);
5526 }
5527 /* Drop the argument parsing error as narrow strings
5528 are also valid. */
5529 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005530#endif
5531
Victor Stinner8c62be82010-05-06 00:08:46 +00005532 if (!PyArg_ParseTuple(args, "O&i|i",
5533 PyUnicode_FSConverter, &ofile,
5534 &flag, &mode))
5535 return NULL;
5536 file = PyBytes_AsString(ofile);
5537 Py_BEGIN_ALLOW_THREADS
5538 fd = open(file, flag, mode);
5539 Py_END_ALLOW_THREADS
5540 if (fd < 0)
5541 return posix_error_with_allocated_filename(ofile);
5542 Py_DECREF(ofile);
5543 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005544}
5545
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005546
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005547PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005548"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005549Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005550
Barry Warsaw53699e91996-12-10 23:23:01 +00005551static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005552posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005553{
Victor Stinner8c62be82010-05-06 00:08:46 +00005554 int fd, res;
5555 if (!PyArg_ParseTuple(args, "i:close", &fd))
5556 return NULL;
5557 if (!_PyVerify_fd(fd))
5558 return posix_error();
5559 Py_BEGIN_ALLOW_THREADS
5560 res = close(fd);
5561 Py_END_ALLOW_THREADS
5562 if (res < 0)
5563 return posix_error();
5564 Py_INCREF(Py_None);
5565 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005566}
5567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005568
Victor Stinner8c62be82010-05-06 00:08:46 +00005569PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005570"closerange(fd_low, fd_high)\n\n\
5571Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5572
5573static PyObject *
5574posix_closerange(PyObject *self, PyObject *args)
5575{
Victor Stinner8c62be82010-05-06 00:08:46 +00005576 int fd_from, fd_to, i;
5577 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5578 return NULL;
5579 Py_BEGIN_ALLOW_THREADS
5580 for (i = fd_from; i < fd_to; i++)
5581 if (_PyVerify_fd(i))
5582 close(i);
5583 Py_END_ALLOW_THREADS
5584 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005585}
5586
5587
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005588PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005589"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005590Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005591
Barry Warsaw53699e91996-12-10 23:23:01 +00005592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005593posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005594{
Victor Stinner8c62be82010-05-06 00:08:46 +00005595 int fd;
5596 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5597 return NULL;
5598 if (!_PyVerify_fd(fd))
5599 return posix_error();
5600 Py_BEGIN_ALLOW_THREADS
5601 fd = dup(fd);
5602 Py_END_ALLOW_THREADS
5603 if (fd < 0)
5604 return posix_error();
5605 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005606}
5607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005608
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005609PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005610"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005611Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005612
Barry Warsaw53699e91996-12-10 23:23:01 +00005613static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005614posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005615{
Victor Stinner8c62be82010-05-06 00:08:46 +00005616 int fd, fd2, res;
5617 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5618 return NULL;
5619 if (!_PyVerify_fd_dup2(fd, fd2))
5620 return posix_error();
5621 Py_BEGIN_ALLOW_THREADS
5622 res = dup2(fd, fd2);
5623 Py_END_ALLOW_THREADS
5624 if (res < 0)
5625 return posix_error();
5626 Py_INCREF(Py_None);
5627 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005628}
5629
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005631PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005632"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005633Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005634
Barry Warsaw53699e91996-12-10 23:23:01 +00005635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005636posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005637{
Victor Stinner8c62be82010-05-06 00:08:46 +00005638 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005639#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005640 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005641#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005642 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005643#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005644 PyObject *posobj;
5645 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5646 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005647#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005648 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5649 switch (how) {
5650 case 0: how = SEEK_SET; break;
5651 case 1: how = SEEK_CUR; break;
5652 case 2: how = SEEK_END; break;
5653 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005654#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005655
5656#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005657 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005658#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005659 pos = PyLong_Check(posobj) ?
5660 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005661#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005662 if (PyErr_Occurred())
5663 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005664
Victor Stinner8c62be82010-05-06 00:08:46 +00005665 if (!_PyVerify_fd(fd))
5666 return posix_error();
5667 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005668#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005669 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005670#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005671 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005672#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005673 Py_END_ALLOW_THREADS
5674 if (res < 0)
5675 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005676
5677#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005678 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005679#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005681#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005682}
5683
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005684
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005686"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005687Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005688
Barry Warsaw53699e91996-12-10 23:23:01 +00005689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005690posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005691{
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 int fd, size;
5693 Py_ssize_t n;
5694 PyObject *buffer;
5695 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5696 return NULL;
5697 if (size < 0) {
5698 errno = EINVAL;
5699 return posix_error();
5700 }
5701 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5702 if (buffer == NULL)
5703 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005704 if (!_PyVerify_fd(fd)) {
5705 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00005706 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005707 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 Py_BEGIN_ALLOW_THREADS
5709 n = read(fd, PyBytes_AS_STRING(buffer), size);
5710 Py_END_ALLOW_THREADS
5711 if (n < 0) {
5712 Py_DECREF(buffer);
5713 return posix_error();
5714 }
5715 if (n != size)
5716 _PyBytes_Resize(&buffer, n);
5717 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005718}
5719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005720
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005721PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005722"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005723Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005724
Barry Warsaw53699e91996-12-10 23:23:01 +00005725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005726posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005727{
Victor Stinner8c62be82010-05-06 00:08:46 +00005728 Py_buffer pbuf;
5729 int fd;
Victor Stinnere6edec22011-01-04 00:29:35 +00005730 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005731
Victor Stinner8c62be82010-05-06 00:08:46 +00005732 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5733 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00005734 if (!_PyVerify_fd(fd)) {
5735 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005736 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00005737 }
Victor Stinnere6edec22011-01-04 00:29:35 +00005738 len = pbuf.len;
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 Py_BEGIN_ALLOW_THREADS
Victor Stinnere6edec22011-01-04 00:29:35 +00005740#if defined(MS_WIN64) || defined(MS_WINDOWS)
5741 if (len > INT_MAX)
5742 len = INT_MAX;
5743 size = write(fd, pbuf.buf, (int)len);
5744#else
Victor Stinner72344792011-01-11 00:04:12 +00005745 size = write(fd, pbuf.buf, len);
Victor Stinnere6edec22011-01-04 00:29:35 +00005746#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005747 Py_END_ALLOW_THREADS
Stefan Krah99439262010-11-26 12:58:05 +00005748 PyBuffer_Release(&pbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 if (size < 0)
5750 return posix_error();
5751 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005752}
5753
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005754#ifdef HAVE_SENDFILE
5755#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
5756static int
5757iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
5758{
5759 int i, j;
5760 *iov = PyMem_New(struct iovec, cnt);
5761 if (*iov == NULL) {
5762 PyErr_NoMemory();
5763 return 0;
5764 }
5765 *buf = PyMem_New(Py_buffer, cnt);
5766 if (*buf == NULL) {
5767 PyMem_Del(*iov);
5768 PyErr_NoMemory();
5769 return 0;
5770 }
5771
5772 for (i = 0; i < cnt; i++) {
5773 if (PyObject_GetBuffer(PySequence_GetItem(seq, i), &(*buf)[i],
5774 type) == -1) {
5775 PyMem_Del(*iov);
5776 for (j = 0; j < i; j++) {
5777 PyBuffer_Release(&(*buf)[j]);
5778 }
5779 PyMem_Del(*buf);
5780 return 0;
5781 }
5782 (*iov)[i].iov_base = (*buf)[i].buf;
5783 (*iov)[i].iov_len = (*buf)[i].len;
5784 }
5785 return 1;
5786}
5787
5788static void
5789iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
5790{
5791 int i;
5792 PyMem_Del(iov);
5793 for (i = 0; i < cnt; i++) {
5794 PyBuffer_Release(&buf[i]);
5795 }
5796 PyMem_Del(buf);
5797}
5798#endif
5799
5800PyDoc_STRVAR(posix_sendfile__doc__,
5801"sendfile(out, in, offset, nbytes) -> byteswritten\n\
5802sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
5803 -> byteswritten\n\
5804Copy nbytes bytes from file descriptor in to file descriptor out.");
5805
5806static PyObject *
5807posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
5808{
5809 int in, out;
5810 Py_ssize_t ret;
5811 off_t offset;
5812
5813#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
5814#ifndef __APPLE__
5815 Py_ssize_t len;
5816#endif
5817 PyObject *headers = NULL, *trailers = NULL;
5818 Py_buffer *hbuf, *tbuf;
5819 off_t sbytes;
5820 struct sf_hdtr sf;
5821 int flags = 0;
5822 sf.headers = NULL;
5823 sf.trailers = NULL;
5824 static char *keywords[] = {"out", "in",
5825 "offset", "count",
5826 "headers", "trailers", "flags", NULL};
5827
5828#ifdef __APPLE__
5829 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
5830 keywords, &out, &in, PyParse_off_t, &offset, PyParse_off_t, &sbytes,
5831#else
5832 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
5833 keywords, &out, &in, PyParse_off_t, &offset, &len,
5834#endif
5835 &headers, &trailers, &flags))
5836 return NULL;
5837 if (headers != NULL) {
5838 if (!PySequence_Check(headers)) {
5839 PyErr_SetString(PyExc_TypeError,
5840 "sendfile() headers must be a sequence or None");
5841 return NULL;
5842 } else {
5843 sf.hdr_cnt = PySequence_Size(headers);
5844 if (sf.hdr_cnt > 0 && !iov_setup(&(sf.headers), &hbuf,
5845 headers, sf.hdr_cnt, PyBUF_SIMPLE))
5846 return NULL;
5847 }
5848 }
5849 if (trailers != NULL) {
5850 if (!PySequence_Check(trailers)) {
5851 PyErr_SetString(PyExc_TypeError,
5852 "sendfile() trailers must be a sequence or None");
5853 return NULL;
5854 } else {
5855 sf.trl_cnt = PySequence_Size(trailers);
5856 if (sf.trl_cnt > 0 && !iov_setup(&(sf.trailers), &tbuf,
5857 trailers, sf.trl_cnt, PyBUF_SIMPLE))
5858 return NULL;
5859 }
5860 }
5861
5862 Py_BEGIN_ALLOW_THREADS
5863#ifdef __APPLE__
5864 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
5865#else
5866 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
5867#endif
5868 Py_END_ALLOW_THREADS
5869
5870 if (sf.headers != NULL)
5871 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
5872 if (sf.trailers != NULL)
5873 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
5874
5875 if (ret < 0) {
5876 if ((errno == EAGAIN) || (errno == EBUSY)) {
5877 if (sbytes != 0) {
5878 // some data has been sent
5879 goto done;
5880 }
5881 else {
5882 // no data has been sent; upper application is supposed
5883 // to retry on EAGAIN or EBUSY
5884 return posix_error();
5885 }
5886 }
5887 return posix_error();
5888 }
5889 goto done;
5890
5891done:
5892 #if !defined(HAVE_LARGEFILE_SUPPORT)
5893 return Py_BuildValue("l", sbytes);
5894 #else
5895 return Py_BuildValue("L", sbytes);
5896 #endif
5897
5898#else
5899 Py_ssize_t count;
5900 PyObject *offobj;
5901 static char *keywords[] = {"out", "in",
5902 "offset", "count", NULL};
5903 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
5904 keywords, &out, &in, &offobj, &count))
5905 return NULL;
5906#ifdef linux
5907 if (offobj == Py_None) {
5908 Py_BEGIN_ALLOW_THREADS
5909 ret = sendfile(out, in, NULL, count);
5910 Py_END_ALLOW_THREADS
5911 if (ret < 0)
5912 return posix_error();
5913 Py_INCREF(Py_None);
5914 return Py_BuildValue("nO", ret, Py_None);
5915 }
5916#endif
5917 PyParse_off_t(offobj, &offset);
5918 Py_BEGIN_ALLOW_THREADS
5919 ret = sendfile(out, in, &offset, count);
5920 Py_END_ALLOW_THREADS
5921 if (ret < 0)
5922 return posix_error();
5923 return Py_BuildValue("n", ret);
5924#endif
5925}
5926#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005927
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005928PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005929"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005930Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005931
Barry Warsaw53699e91996-12-10 23:23:01 +00005932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005933posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005934{
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 int fd;
5936 STRUCT_STAT st;
5937 int res;
5938 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5939 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005940#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 /* on OpenVMS we must ensure that all bytes are written to the file */
5942 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005943#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 if (!_PyVerify_fd(fd))
5945 return posix_error();
5946 Py_BEGIN_ALLOW_THREADS
5947 res = FSTAT(fd, &st);
5948 Py_END_ALLOW_THREADS
5949 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005950#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005952#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005954#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 }
Tim Peters5aa91602002-01-30 05:46:57 +00005956
Victor Stinner8c62be82010-05-06 00:08:46 +00005957 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005958}
5959
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005960PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005961"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005962Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005963connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005964
5965static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005966posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005967{
Victor Stinner8c62be82010-05-06 00:08:46 +00005968 int fd;
5969 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5970 return NULL;
5971 if (!_PyVerify_fd(fd))
5972 return PyBool_FromLong(0);
5973 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005974}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005975
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005976#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005977PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005978"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005980
Barry Warsaw53699e91996-12-10 23:23:01 +00005981static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005982posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005983{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005984#if defined(PYOS_OS2)
5985 HFILE read, write;
5986 APIRET rc;
5987
Victor Stinner8c62be82010-05-06 00:08:46 +00005988 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005989 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005991 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005992 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005993
5994 return Py_BuildValue("(ii)", read, write);
5995#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005996#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 int fds[2];
5998 int res;
5999 Py_BEGIN_ALLOW_THREADS
6000 res = pipe(fds);
6001 Py_END_ALLOW_THREADS
6002 if (res != 0)
6003 return posix_error();
6004 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006005#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00006006 HANDLE read, write;
6007 int read_fd, write_fd;
6008 BOOL ok;
6009 Py_BEGIN_ALLOW_THREADS
6010 ok = CreatePipe(&read, &write, NULL, 0);
6011 Py_END_ALLOW_THREADS
6012 if (!ok)
6013 return win32_error("CreatePipe", NULL);
6014 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6015 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6016 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006017#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006018#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006019}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006020#endif /* HAVE_PIPE */
6021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006022
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006023#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006024PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006025"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006026Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006027
Barry Warsaw53699e91996-12-10 23:23:01 +00006028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006029posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006030{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00006031 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00006032 char *filename;
6033 int mode = 0666;
6034 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00006035 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
6036 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00006037 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00006038 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 Py_BEGIN_ALLOW_THREADS
6040 res = mkfifo(filename, mode);
6041 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00006042 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00006043 if (res < 0)
6044 return posix_error();
6045 Py_INCREF(Py_None);
6046 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006047}
6048#endif
6049
6050
Neal Norwitz11690112002-07-30 01:08:28 +00006051#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006053"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006054Create a filesystem node (file, device special file or named pipe)\n\
6055named filename. mode specifies both the permissions to use and the\n\
6056type of node to be created, being combined (bitwise OR) with one of\n\
6057S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006058device defines the newly created device special file (probably using\n\
6059os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006060
6061
6062static PyObject *
6063posix_mknod(PyObject *self, PyObject *args)
6064{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00006065 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00006066 char *filename;
6067 int mode = 0600;
6068 int device = 0;
6069 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00006070 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
6071 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00006072 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00006073 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00006074 Py_BEGIN_ALLOW_THREADS
6075 res = mknod(filename, mode, device);
6076 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00006077 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00006078 if (res < 0)
6079 return posix_error();
6080 Py_INCREF(Py_None);
6081 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006082}
6083#endif
6084
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006085#ifdef HAVE_DEVICE_MACROS
6086PyDoc_STRVAR(posix_major__doc__,
6087"major(device) -> major number\n\
6088Extracts a device major number from a raw device number.");
6089
6090static PyObject *
6091posix_major(PyObject *self, PyObject *args)
6092{
Victor Stinner8c62be82010-05-06 00:08:46 +00006093 int device;
6094 if (!PyArg_ParseTuple(args, "i:major", &device))
6095 return NULL;
6096 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006097}
6098
6099PyDoc_STRVAR(posix_minor__doc__,
6100"minor(device) -> minor number\n\
6101Extracts a device minor number from a raw device number.");
6102
6103static PyObject *
6104posix_minor(PyObject *self, PyObject *args)
6105{
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 int device;
6107 if (!PyArg_ParseTuple(args, "i:minor", &device))
6108 return NULL;
6109 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006110}
6111
6112PyDoc_STRVAR(posix_makedev__doc__,
6113"makedev(major, minor) -> device number\n\
6114Composes a raw device number from the major and minor device numbers.");
6115
6116static PyObject *
6117posix_makedev(PyObject *self, PyObject *args)
6118{
Victor Stinner8c62be82010-05-06 00:08:46 +00006119 int major, minor;
6120 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6121 return NULL;
6122 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006123}
6124#endif /* device macros */
6125
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006127#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006128PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006129"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006130Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006131
Barry Warsaw53699e91996-12-10 23:23:01 +00006132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006133posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006134{
Victor Stinner8c62be82010-05-06 00:08:46 +00006135 int fd;
6136 off_t length;
6137 int res;
6138 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006139
Victor Stinner8c62be82010-05-06 00:08:46 +00006140 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6141 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006142
6143#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006144 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006145#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006146 length = PyLong_Check(lenobj) ?
6147 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006148#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 if (PyErr_Occurred())
6150 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006151
Victor Stinner8c62be82010-05-06 00:08:46 +00006152 Py_BEGIN_ALLOW_THREADS
6153 res = ftruncate(fd, length);
6154 Py_END_ALLOW_THREADS
6155 if (res < 0)
6156 return posix_error();
6157 Py_INCREF(Py_None);
6158 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006159}
6160#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006161
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006162#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006164"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006166
Fred Drake762e2061999-08-26 17:23:54 +00006167/* Save putenv() parameters as values here, so we can collect them when they
6168 * get re-set with another call for the same key. */
6169static PyObject *posix_putenv_garbage;
6170
Tim Peters5aa91602002-01-30 05:46:57 +00006171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006172posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006173{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006174#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006175 wchar_t *s1, *s2;
6176 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006177#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006178 PyObject *os1, *os2;
6179 char *s1, *s2;
6180 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006181#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006182 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006184
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006185#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 if (!PyArg_ParseTuple(args,
6187 "uu:putenv",
6188 &s1, &s2))
6189 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00006190#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006191 if (!PyArg_ParseTuple(args,
6192 "O&O&:putenv",
6193 PyUnicode_FSConverter, &os1,
6194 PyUnicode_FSConverter, &os2))
6195 return NULL;
6196 s1 = PyBytes_AsString(os1);
6197 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006198#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006199
6200#if defined(PYOS_OS2)
6201 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6202 APIRET rc;
6203
Guido van Rossumd48f2521997-12-05 22:19:34 +00006204 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00006205 if (rc != NO_ERROR) {
6206 os2_error(rc);
6207 goto error;
6208 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006209
6210 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6211 APIRET rc;
6212
Guido van Rossumd48f2521997-12-05 22:19:34 +00006213 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00006214 if (rc != NO_ERROR) {
6215 os2_error(rc);
6216 goto error;
6217 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006218 } else {
6219#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 /* XXX This can leak memory -- not easy to fix :-( */
6221 /* len includes space for a trailing \0; the size arg to
6222 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006223#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006224 len = wcslen(s1) + wcslen(s2) + 2;
6225 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006226#else
Victor Stinner84ae1182010-05-06 22:05:07 +00006227 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00006228 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006229#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006230 if (newstr == NULL) {
6231 PyErr_NoMemory();
6232 goto error;
6233 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006234#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006235 newenv = PyUnicode_AsUnicode(newstr);
6236 _snwprintf(newenv, len, L"%s=%s", s1, s2);
6237 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006239 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006241#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006242 newenv = PyBytes_AS_STRING(newstr);
6243 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6244 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006245 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006246 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006248#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006249
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 /* Install the first arg and newstr in posix_putenv_garbage;
6251 * this will cause previous value to be collected. This has to
6252 * happen after the real putenv() call because the old value
6253 * was still accessible until then. */
6254 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006255#ifdef MS_WINDOWS
6256 PyTuple_GET_ITEM(args, 0),
6257#else
6258 os1,
6259#endif
6260 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 /* really not much we can do; just leak */
6262 PyErr_Clear();
6263 }
6264 else {
6265 Py_DECREF(newstr);
6266 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006267
6268#if defined(PYOS_OS2)
6269 }
6270#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006271
Martin v. Löwis011e8422009-05-05 04:43:17 +00006272#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 Py_DECREF(os1);
6274 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006275#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006276 Py_RETURN_NONE;
6277
6278error:
6279#ifndef MS_WINDOWS
6280 Py_DECREF(os1);
6281 Py_DECREF(os2);
6282#endif
6283 Py_XDECREF(newstr);
6284 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006285}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006286#endif /* putenv */
6287
Guido van Rossumc524d952001-10-19 01:31:59 +00006288#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006289PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006290"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006291Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006292
6293static PyObject *
6294posix_unsetenv(PyObject *self, PyObject *args)
6295{
Victor Stinner84ae1182010-05-06 22:05:07 +00006296#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006298
Victor Stinner8c62be82010-05-06 00:08:46 +00006299 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6300 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006301#else
6302 PyObject *os1;
6303 char *s1;
6304
6305 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6306 PyUnicode_FSConverter, &os1))
6307 return NULL;
6308 s1 = PyBytes_AsString(os1);
6309#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006310
Victor Stinner8c62be82010-05-06 00:08:46 +00006311 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006312
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 /* Remove the key from posix_putenv_garbage;
6314 * this will cause it to be collected. This has to
6315 * happen after the real unsetenv() call because the
6316 * old value was still accessible until then.
6317 */
6318 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006319#ifdef MS_WINDOWS
6320 PyTuple_GET_ITEM(args, 0)
6321#else
6322 os1
6323#endif
6324 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006325 /* really not much we can do; just leak */
6326 PyErr_Clear();
6327 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006328
Victor Stinner84ae1182010-05-06 22:05:07 +00006329#ifndef MS_WINDOWS
6330 Py_DECREF(os1);
6331#endif
6332 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006333}
6334#endif /* unsetenv */
6335
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006336PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006337"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006338Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006339
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006341posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006342{
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 int code;
6344 char *message;
6345 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6346 return NULL;
6347 message = strerror(code);
6348 if (message == NULL) {
6349 PyErr_SetString(PyExc_ValueError,
6350 "strerror() argument out of range");
6351 return NULL;
6352 }
6353 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006354}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006355
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006356
Guido van Rossumc9641791998-08-04 15:26:23 +00006357#ifdef HAVE_SYS_WAIT_H
6358
Fred Drake106c1a02002-04-23 15:58:02 +00006359#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006360PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006361"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006362Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006363
6364static PyObject *
6365posix_WCOREDUMP(PyObject *self, PyObject *args)
6366{
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 WAIT_TYPE status;
6368 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006369
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6371 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006372
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006374}
6375#endif /* WCOREDUMP */
6376
6377#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006378PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006379"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006380Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006381job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006382
6383static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006384posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006385{
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 WAIT_TYPE status;
6387 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006388
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6390 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006391
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006393}
6394#endif /* WIFCONTINUED */
6395
Guido van Rossumc9641791998-08-04 15:26:23 +00006396#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006397PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006398"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006399Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006400
6401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006402posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006403{
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 WAIT_TYPE status;
6405 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006406
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6408 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006409
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006411}
6412#endif /* WIFSTOPPED */
6413
6414#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006415PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006416"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006417Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006418
6419static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006420posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006421{
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 WAIT_TYPE status;
6423 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006424
Victor Stinner8c62be82010-05-06 00:08:46 +00006425 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6426 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006427
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006429}
6430#endif /* WIFSIGNALED */
6431
6432#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006433PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006434"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006435Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006436system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006437
6438static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006439posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006440{
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 WAIT_TYPE status;
6442 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006443
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6445 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006446
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006448}
6449#endif /* WIFEXITED */
6450
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006451#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006452PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006453"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006454Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006455
6456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006457posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006458{
Victor Stinner8c62be82010-05-06 00:08:46 +00006459 WAIT_TYPE status;
6460 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006461
Victor Stinner8c62be82010-05-06 00:08:46 +00006462 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6463 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006464
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006466}
6467#endif /* WEXITSTATUS */
6468
6469#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006470PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006471"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006472Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006473value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006474
6475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006476posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006477{
Victor Stinner8c62be82010-05-06 00:08:46 +00006478 WAIT_TYPE status;
6479 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006480
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6482 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006483
Victor Stinner8c62be82010-05-06 00:08:46 +00006484 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006485}
6486#endif /* WTERMSIG */
6487
6488#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006489PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006490"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006491Return the signal that stopped the process that provided\n\
6492the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006493
6494static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006495posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006496{
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 WAIT_TYPE status;
6498 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006499
Victor Stinner8c62be82010-05-06 00:08:46 +00006500 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6501 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006502
Victor Stinner8c62be82010-05-06 00:08:46 +00006503 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006504}
6505#endif /* WSTOPSIG */
6506
6507#endif /* HAVE_SYS_WAIT_H */
6508
6509
Thomas Wouters477c8d52006-05-27 19:21:47 +00006510#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006511#ifdef _SCO_DS
6512/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6513 needed definitions in sys/statvfs.h */
6514#define _SVID3
6515#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006516#include <sys/statvfs.h>
6517
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006518static PyObject*
6519_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6521 if (v == NULL)
6522 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006523
6524#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006525 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6526 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6527 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6528 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6529 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6530 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6531 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6532 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6533 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6534 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006535#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6537 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6538 PyStructSequence_SET_ITEM(v, 2,
6539 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6540 PyStructSequence_SET_ITEM(v, 3,
6541 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6542 PyStructSequence_SET_ITEM(v, 4,
6543 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6544 PyStructSequence_SET_ITEM(v, 5,
6545 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6546 PyStructSequence_SET_ITEM(v, 6,
6547 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6548 PyStructSequence_SET_ITEM(v, 7,
6549 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6550 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6551 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006552#endif
6553
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006555}
6556
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006557PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006558"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006559Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006560
6561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006562posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006563{
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 int fd, res;
6565 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006566
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6568 return NULL;
6569 Py_BEGIN_ALLOW_THREADS
6570 res = fstatvfs(fd, &st);
6571 Py_END_ALLOW_THREADS
6572 if (res != 0)
6573 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006574
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006576}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006577#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006578
6579
Thomas Wouters477c8d52006-05-27 19:21:47 +00006580#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006581#include <sys/statvfs.h>
6582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006583PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006584"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006585Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006586
6587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006588posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006589{
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 char *path;
6591 int res;
6592 struct statvfs st;
6593 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6594 return NULL;
6595 Py_BEGIN_ALLOW_THREADS
6596 res = statvfs(path, &st);
6597 Py_END_ALLOW_THREADS
6598 if (res != 0)
6599 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006600
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006602}
6603#endif /* HAVE_STATVFS */
6604
Fred Drakec9680921999-12-13 16:37:25 +00006605/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6606 * It maps strings representing configuration variable names to
6607 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006608 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006609 * rarely-used constants. There are three separate tables that use
6610 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006611 *
6612 * This code is always included, even if none of the interfaces that
6613 * need it are included. The #if hackery needed to avoid it would be
6614 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006615 */
6616struct constdef {
6617 char *name;
6618 long value;
6619};
6620
Fred Drake12c6e2d1999-12-14 21:25:03 +00006621static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006622conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006623 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006624{
Christian Heimes217cfd12007-12-02 14:31:20 +00006625 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006626 *valuep = PyLong_AS_LONG(arg);
6627 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006628 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006629 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00006630 /* look up the value in the table using a binary search */
6631 size_t lo = 0;
6632 size_t mid;
6633 size_t hi = tablesize;
6634 int cmp;
6635 const char *confname;
6636 if (!PyUnicode_Check(arg)) {
6637 PyErr_SetString(PyExc_TypeError,
6638 "configuration names must be strings or integers");
6639 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 }
Stefan Krah0e803b32010-11-26 16:16:47 +00006641 confname = _PyUnicode_AsString(arg);
6642 if (confname == NULL)
6643 return 0;
6644 while (lo < hi) {
6645 mid = (lo + hi) / 2;
6646 cmp = strcmp(confname, table[mid].name);
6647 if (cmp < 0)
6648 hi = mid;
6649 else if (cmp > 0)
6650 lo = mid + 1;
6651 else {
6652 *valuep = table[mid].value;
6653 return 1;
6654 }
6655 }
6656 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6657 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006659}
6660
6661
6662#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6663static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006664#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006666#endif
6667#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006669#endif
Fred Drakec9680921999-12-13 16:37:25 +00006670#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006672#endif
6673#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006674 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006675#endif
6676#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006677 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006678#endif
6679#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006681#endif
6682#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006683 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006684#endif
6685#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006687#endif
6688#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006690#endif
6691#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006693#endif
6694#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006696#endif
6697#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006698 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006699#endif
6700#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006701 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006702#endif
6703#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006704 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006705#endif
6706#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006707 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006708#endif
6709#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006711#endif
6712#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006714#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006715#ifdef _PC_ACL_ENABLED
6716 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6717#endif
6718#ifdef _PC_MIN_HOLE_SIZE
6719 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6720#endif
6721#ifdef _PC_ALLOC_SIZE_MIN
6722 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6723#endif
6724#ifdef _PC_REC_INCR_XFER_SIZE
6725 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6726#endif
6727#ifdef _PC_REC_MAX_XFER_SIZE
6728 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6729#endif
6730#ifdef _PC_REC_MIN_XFER_SIZE
6731 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6732#endif
6733#ifdef _PC_REC_XFER_ALIGN
6734 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6735#endif
6736#ifdef _PC_SYMLINK_MAX
6737 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6738#endif
6739#ifdef _PC_XATTR_ENABLED
6740 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6741#endif
6742#ifdef _PC_XATTR_EXISTS
6743 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6744#endif
6745#ifdef _PC_TIMESTAMP_RESOLUTION
6746 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6747#endif
Fred Drakec9680921999-12-13 16:37:25 +00006748};
6749
Fred Drakec9680921999-12-13 16:37:25 +00006750static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006751conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006752{
6753 return conv_confname(arg, valuep, posix_constants_pathconf,
6754 sizeof(posix_constants_pathconf)
6755 / sizeof(struct constdef));
6756}
6757#endif
6758
6759#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006760PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006761"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006762Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006763If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006764
6765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006766posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006767{
6768 PyObject *result = NULL;
6769 int name, fd;
6770
Fred Drake12c6e2d1999-12-14 21:25:03 +00006771 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6772 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006773 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006774
Stefan Krah0e803b32010-11-26 16:16:47 +00006775 errno = 0;
6776 limit = fpathconf(fd, name);
6777 if (limit == -1 && errno != 0)
6778 posix_error();
6779 else
6780 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006781 }
6782 return result;
6783}
6784#endif
6785
6786
6787#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006788PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006789"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006790Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006791If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006792
6793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006794posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006795{
6796 PyObject *result = NULL;
6797 int name;
6798 char *path;
6799
6800 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6801 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006803
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 errno = 0;
6805 limit = pathconf(path, name);
6806 if (limit == -1 && errno != 0) {
6807 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00006808 /* could be a path or name problem */
6809 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006810 else
Stefan Krah99439262010-11-26 12:58:05 +00006811 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 }
6813 else
6814 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006815 }
6816 return result;
6817}
6818#endif
6819
6820#ifdef HAVE_CONFSTR
6821static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006822#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006824#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006825#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006827#endif
6828#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006830#endif
Fred Draked86ed291999-12-15 15:34:33 +00006831#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006833#endif
6834#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006836#endif
6837#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006839#endif
6840#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006842#endif
Fred Drakec9680921999-12-13 16:37:25 +00006843#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006845#endif
6846#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006848#endif
6849#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006851#endif
6852#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006854#endif
6855#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006857#endif
6858#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006860#endif
6861#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006863#endif
6864#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006866#endif
Fred Draked86ed291999-12-15 15:34:33 +00006867#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006869#endif
Fred Drakec9680921999-12-13 16:37:25 +00006870#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006872#endif
Fred Draked86ed291999-12-15 15:34:33 +00006873#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006875#endif
6876#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006878#endif
6879#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006881#endif
6882#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006884#endif
Fred Drakec9680921999-12-13 16:37:25 +00006885#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006887#endif
6888#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006890#endif
6891#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006893#endif
6894#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006896#endif
6897#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006899#endif
6900#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006902#endif
6903#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006905#endif
6906#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006908#endif
6909#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006911#endif
6912#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006914#endif
6915#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006917#endif
6918#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006920#endif
6921#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006923#endif
6924#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006926#endif
6927#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006929#endif
6930#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006932#endif
Fred Draked86ed291999-12-15 15:34:33 +00006933#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006935#endif
6936#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006938#endif
6939#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006941#endif
6942#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006944#endif
6945#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006947#endif
6948#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006950#endif
6951#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006953#endif
6954#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006956#endif
6957#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006959#endif
6960#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006962#endif
6963#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006965#endif
6966#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006968#endif
6969#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006971#endif
Fred Drakec9680921999-12-13 16:37:25 +00006972};
6973
6974static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006975conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006976{
6977 return conv_confname(arg, valuep, posix_constants_confstr,
6978 sizeof(posix_constants_confstr)
6979 / sizeof(struct constdef));
6980}
6981
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006982PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006983"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006984Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006985
6986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006987posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006988{
6989 PyObject *result = NULL;
6990 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006991 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00006992 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006993
Victor Stinnercb043522010-09-10 23:49:04 +00006994 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6995 return NULL;
6996
6997 errno = 0;
6998 len = confstr(name, buffer, sizeof(buffer));
6999 if (len == 0) {
7000 if (errno) {
7001 posix_error();
7002 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00007003 }
7004 else {
Victor Stinnercb043522010-09-10 23:49:04 +00007005 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00007006 }
7007 }
Victor Stinnercb043522010-09-10 23:49:04 +00007008
7009 if ((unsigned int)len >= sizeof(buffer)) {
7010 char *buf = PyMem_Malloc(len);
7011 if (buf == NULL)
7012 return PyErr_NoMemory();
7013 confstr(name, buf, len);
7014 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
7015 PyMem_Free(buf);
7016 }
7017 else
7018 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007019 return result;
7020}
7021#endif
7022
7023
7024#ifdef HAVE_SYSCONF
7025static struct constdef posix_constants_sysconf[] = {
7026#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00007028#endif
7029#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00007031#endif
7032#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007034#endif
7035#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007037#endif
7038#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007040#endif
7041#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00007043#endif
7044#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00007046#endif
7047#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007049#endif
7050#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00007052#endif
7053#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007055#endif
Fred Draked86ed291999-12-15 15:34:33 +00007056#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007058#endif
7059#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00007061#endif
Fred Drakec9680921999-12-13 16:37:25 +00007062#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007064#endif
Fred Drakec9680921999-12-13 16:37:25 +00007065#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007067#endif
7068#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007070#endif
7071#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007073#endif
7074#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007076#endif
7077#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007079#endif
Fred Draked86ed291999-12-15 15:34:33 +00007080#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00007082#endif
Fred Drakec9680921999-12-13 16:37:25 +00007083#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007085#endif
7086#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007088#endif
7089#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007091#endif
7092#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007094#endif
7095#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007097#endif
Fred Draked86ed291999-12-15 15:34:33 +00007098#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00007100#endif
Fred Drakec9680921999-12-13 16:37:25 +00007101#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007103#endif
7104#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007106#endif
7107#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007109#endif
7110#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007112#endif
7113#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007115#endif
7116#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007118#endif
7119#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007121#endif
7122#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007124#endif
7125#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007127#endif
7128#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007130#endif
7131#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007133#endif
7134#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007136#endif
7137#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007139#endif
7140#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007142#endif
7143#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007145#endif
7146#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007148#endif
7149#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007151#endif
7152#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007154#endif
7155#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007156 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007157#endif
7158#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007160#endif
7161#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007163#endif
7164#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007166#endif
7167#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00007168 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007169#endif
Fred Draked86ed291999-12-15 15:34:33 +00007170#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007172#endif
Fred Drakec9680921999-12-13 16:37:25 +00007173#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007175#endif
7176#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007178#endif
7179#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007181#endif
Fred Draked86ed291999-12-15 15:34:33 +00007182#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007184#endif
Fred Drakec9680921999-12-13 16:37:25 +00007185#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007187#endif
Fred Draked86ed291999-12-15 15:34:33 +00007188#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007190#endif
7191#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007193#endif
Fred Drakec9680921999-12-13 16:37:25 +00007194#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007196#endif
7197#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007199#endif
7200#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007202#endif
7203#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007205#endif
Fred Draked86ed291999-12-15 15:34:33 +00007206#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00007208#endif
Fred Drakec9680921999-12-13 16:37:25 +00007209#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00007210 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00007211#endif
7212#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00007214#endif
7215#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007216 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007217#endif
7218#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00007220#endif
7221#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00007223#endif
7224#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00007226#endif
7227#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00007229#endif
Fred Draked86ed291999-12-15 15:34:33 +00007230#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00007231 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00007232#endif
Fred Drakec9680921999-12-13 16:37:25 +00007233#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007235#endif
7236#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007237 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007238#endif
Fred Draked86ed291999-12-15 15:34:33 +00007239#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007241#endif
Fred Drakec9680921999-12-13 16:37:25 +00007242#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007243 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007244#endif
7245#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007247#endif
7248#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007250#endif
7251#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007252 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007253#endif
7254#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007256#endif
7257#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007258 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007259#endif
7260#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007262#endif
7263#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007264 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00007265#endif
7266#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007267 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007268#endif
Fred Draked86ed291999-12-15 15:34:33 +00007269#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007270 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007271#endif
7272#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007273 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007274#endif
Fred Drakec9680921999-12-13 16:37:25 +00007275#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00007276 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007277#endif
7278#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007279 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007280#endif
7281#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007282 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007283#endif
7284#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007285 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007286#endif
7287#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007288 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007289#endif
7290#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007291 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007292#endif
7293#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00007294 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007295#endif
7296#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007297 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007298#endif
7299#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007300 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007301#endif
7302#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007303 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007304#endif
7305#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007306 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007307#endif
7308#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007309 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007310#endif
7311#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007312 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007313#endif
7314#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007315 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007316#endif
7317#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007318 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007319#endif
7320#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007321 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007322#endif
7323#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007324 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007325#endif
7326#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007327 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007328#endif
7329#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007330 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007331#endif
7332#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007333 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007334#endif
7335#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007336 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007337#endif
7338#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007339 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007340#endif
7341#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007342 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007343#endif
7344#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007345 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007346#endif
7347#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007348 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007349#endif
7350#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007351 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007352#endif
7353#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007354 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007355#endif
7356#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007357 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007358#endif
7359#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007360 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007361#endif
7362#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007363 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007364#endif
7365#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007366 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007367#endif
7368#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007369 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007370#endif
7371#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007372 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007373#endif
7374#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007375 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007376#endif
7377#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007378 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007379#endif
Fred Draked86ed291999-12-15 15:34:33 +00007380#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007382#endif
Fred Drakec9680921999-12-13 16:37:25 +00007383#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007384 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007385#endif
7386#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007387 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007388#endif
7389#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007391#endif
7392#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007393 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007394#endif
7395#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007396 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007397#endif
7398#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007399 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007400#endif
7401#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007402 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007403#endif
7404#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007405 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007406#endif
7407#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007408 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007409#endif
7410#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007411 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007412#endif
7413#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007414 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007415#endif
7416#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007417 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007418#endif
7419#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007420 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007421#endif
7422#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007423 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007424#endif
7425#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007426 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007427#endif
7428#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007430#endif
7431#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007432 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007433#endif
7434#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007435 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007436#endif
7437#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007438 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007439#endif
7440#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007441 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007442#endif
7443#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007444 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007445#endif
7446#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007447 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007448#endif
7449#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007450 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007451#endif
7452#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007453 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007454#endif
7455#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007456 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007457#endif
7458#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007459 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007460#endif
7461#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007462 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007463#endif
7464#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007465 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007466#endif
7467#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007468 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007469#endif
7470#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007471 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007472#endif
7473#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007474 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007475#endif
7476#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007477 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007478#endif
7479#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007480 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007481#endif
7482#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007483 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007484#endif
7485#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007486 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007487#endif
7488#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007489 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007490#endif
7491#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007492 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007493#endif
7494#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007495 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007496#endif
7497#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007498 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007499#endif
7500#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007501 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007502#endif
7503#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007504 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007505#endif
7506#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007507 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007508#endif
7509#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007510 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007511#endif
7512#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007513 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007514#endif
7515#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007516 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007517#endif
7518};
7519
7520static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007521conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007522{
7523 return conv_confname(arg, valuep, posix_constants_sysconf,
7524 sizeof(posix_constants_sysconf)
7525 / sizeof(struct constdef));
7526}
7527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007528PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007529"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007530Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007531
7532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007533posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007534{
7535 PyObject *result = NULL;
7536 int name;
7537
7538 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7539 int value;
7540
7541 errno = 0;
7542 value = sysconf(name);
7543 if (value == -1 && errno != 0)
7544 posix_error();
7545 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007546 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007547 }
7548 return result;
7549}
7550#endif
7551
7552
Fred Drakebec628d1999-12-15 18:31:10 +00007553/* This code is used to ensure that the tables of configuration value names
7554 * are in sorted order as required by conv_confname(), and also to build the
7555 * the exported dictionaries that are used to publish information about the
7556 * names available on the host platform.
7557 *
7558 * Sorting the table at runtime ensures that the table is properly ordered
7559 * when used, even for platforms we're not able to test on. It also makes
7560 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007561 */
Fred Drakebec628d1999-12-15 18:31:10 +00007562
7563static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007564cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007565{
7566 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007567 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007568 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007570
7571 return strcmp(c1->name, c2->name);
7572}
7573
7574static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007575setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007576 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007577{
Fred Drakebec628d1999-12-15 18:31:10 +00007578 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007579 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007580
7581 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7582 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007583 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007585
Barry Warsaw3155db32000-04-13 15:20:40 +00007586 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007587 PyObject *o = PyLong_FromLong(table[i].value);
7588 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7589 Py_XDECREF(o);
7590 Py_DECREF(d);
7591 return -1;
7592 }
7593 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007594 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007595 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007596}
7597
Fred Drakebec628d1999-12-15 18:31:10 +00007598/* Return -1 on failure, 0 on success. */
7599static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007600setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007601{
7602#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007603 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007604 sizeof(posix_constants_pathconf)
7605 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007606 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007607 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007608#endif
7609#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007610 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007611 sizeof(posix_constants_confstr)
7612 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007613 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007614 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007615#endif
7616#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007617 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007618 sizeof(posix_constants_sysconf)
7619 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007620 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00007621 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007622#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007623 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007624}
Fred Draked86ed291999-12-15 15:34:33 +00007625
7626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007627PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007628"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007629Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007630in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007631
7632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007633posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007634{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007635 abort();
7636 /*NOTREACHED*/
7637 Py_FatalError("abort() called from Python code didn't abort!");
7638 return NULL;
7639}
Fred Drakebec628d1999-12-15 18:31:10 +00007640
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007641#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007642PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007643"startfile(filepath [, operation]) - Start a file with its associated\n\
7644application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007645\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007646When \"operation\" is not specified or \"open\", this acts like\n\
7647double-clicking the file in Explorer, or giving the file name as an\n\
7648argument to the DOS \"start\" command: the file is opened with whatever\n\
7649application (if any) its extension is associated.\n\
7650When another \"operation\" is given, it specifies what should be done with\n\
7651the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007652\n\
7653startfile returns as soon as the associated application is launched.\n\
7654There is no option to wait for the application to close, and no way\n\
7655to retrieve the application's exit status.\n\
7656\n\
7657The filepath is relative to the current directory. If you want to use\n\
7658an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007659the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007660
7661static PyObject *
7662win32_startfile(PyObject *self, PyObject *args)
7663{
Victor Stinner8c62be82010-05-06 00:08:46 +00007664 PyObject *ofilepath;
7665 char *filepath;
7666 char *operation = NULL;
7667 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007668
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 PyObject *unipath, *woperation = NULL;
7670 if (!PyArg_ParseTuple(args, "U|s:startfile",
7671 &unipath, &operation)) {
7672 PyErr_Clear();
7673 goto normal;
7674 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007675
Victor Stinner8c62be82010-05-06 00:08:46 +00007676 if (operation) {
7677 woperation = PyUnicode_DecodeASCII(operation,
7678 strlen(operation), NULL);
7679 if (!woperation) {
7680 PyErr_Clear();
7681 operation = NULL;
7682 goto normal;
7683 }
7684 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007685
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 Py_BEGIN_ALLOW_THREADS
7687 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7688 PyUnicode_AS_UNICODE(unipath),
7689 NULL, NULL, SW_SHOWNORMAL);
7690 Py_END_ALLOW_THREADS
7691
7692 Py_XDECREF(woperation);
7693 if (rc <= (HINSTANCE)32) {
7694 PyObject *errval = win32_error_unicode("startfile",
7695 PyUnicode_AS_UNICODE(unipath));
7696 return errval;
7697 }
7698 Py_INCREF(Py_None);
7699 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007700
7701normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7703 PyUnicode_FSConverter, &ofilepath,
7704 &operation))
7705 return NULL;
7706 filepath = PyBytes_AsString(ofilepath);
7707 Py_BEGIN_ALLOW_THREADS
7708 rc = ShellExecute((HWND)0, operation, filepath,
7709 NULL, NULL, SW_SHOWNORMAL);
7710 Py_END_ALLOW_THREADS
7711 if (rc <= (HINSTANCE)32) {
7712 PyObject *errval = win32_error("startfile", filepath);
7713 Py_DECREF(ofilepath);
7714 return errval;
7715 }
7716 Py_DECREF(ofilepath);
7717 Py_INCREF(Py_None);
7718 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007719}
7720#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007721
Martin v. Löwis438b5342002-12-27 10:16:42 +00007722#ifdef HAVE_GETLOADAVG
7723PyDoc_STRVAR(posix_getloadavg__doc__,
7724"getloadavg() -> (float, float, float)\n\n\
7725Return the number of processes in the system run queue averaged over\n\
7726the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7727was unobtainable");
7728
7729static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007730posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007731{
7732 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007733 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00007734 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7735 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007736 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00007737 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007738}
7739#endif
7740
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007741#ifdef MS_WINDOWS
7742
7743PyDoc_STRVAR(win32_urandom__doc__,
7744"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007745Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007746
7747typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7748 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7749 DWORD dwFlags );
7750typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7751 BYTE *pbBuffer );
7752
7753static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007754/* This handle is never explicitly released. Instead, the operating
7755 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007756static HCRYPTPROV hCryptProv = 0;
7757
Tim Peters4ad82172004-08-30 17:02:04 +00007758static PyObject*
7759win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007760{
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 int howMany;
7762 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007763
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 /* Read arguments */
7765 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7766 return NULL;
7767 if (howMany < 0)
7768 return PyErr_Format(PyExc_ValueError,
7769 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007770
Victor Stinner8c62be82010-05-06 00:08:46 +00007771 if (hCryptProv == 0) {
7772 HINSTANCE hAdvAPI32 = NULL;
7773 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007774
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 /* Obtain handle to the DLL containing CryptoAPI
7776 This should not fail */
7777 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7778 if(hAdvAPI32 == NULL)
7779 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007780
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 /* Obtain pointers to the CryptoAPI functions
7782 This will fail on some early versions of Win95 */
7783 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7784 hAdvAPI32,
7785 "CryptAcquireContextA");
7786 if (pCryptAcquireContext == NULL)
7787 return PyErr_Format(PyExc_NotImplementedError,
7788 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007789
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7791 hAdvAPI32, "CryptGenRandom");
7792 if (pCryptGenRandom == NULL)
7793 return PyErr_Format(PyExc_NotImplementedError,
7794 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007795
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 /* Acquire context */
7797 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7798 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7799 return win32_error("CryptAcquireContext", NULL);
7800 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007801
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 /* Allocate bytes */
7803 result = PyBytes_FromStringAndSize(NULL, howMany);
7804 if (result != NULL) {
7805 /* Get random data */
7806 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7807 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7808 PyBytes_AS_STRING(result))) {
7809 Py_DECREF(result);
7810 return win32_error("CryptGenRandom", NULL);
7811 }
7812 }
7813 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007814}
7815#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007816
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007817PyDoc_STRVAR(device_encoding__doc__,
7818"device_encoding(fd) -> str\n\n\
7819Return a string describing the encoding of the device\n\
7820if the output is a terminal; else return None.");
7821
7822static PyObject *
7823device_encoding(PyObject *self, PyObject *args)
7824{
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 int fd;
7826 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7827 return NULL;
7828 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7829 Py_INCREF(Py_None);
7830 return Py_None;
7831 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007832#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 if (fd == 0) {
7834 char buf[100];
7835 sprintf(buf, "cp%d", GetConsoleCP());
7836 return PyUnicode_FromString(buf);
7837 }
7838 if (fd == 1 || fd == 2) {
7839 char buf[100];
7840 sprintf(buf, "cp%d", GetConsoleOutputCP());
7841 return PyUnicode_FromString(buf);
7842 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007843#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 {
7845 char *codeset = nl_langinfo(CODESET);
7846 if (codeset != NULL && codeset[0] != 0)
7847 return PyUnicode_FromString(codeset);
7848 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007849#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007850 Py_INCREF(Py_None);
7851 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007852}
7853
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007854#ifdef __VMS
7855/* Use openssl random routine */
7856#include <openssl/rand.h>
7857PyDoc_STRVAR(vms_urandom__doc__,
7858"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007859Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007860
7861static PyObject*
7862vms_urandom(PyObject *self, PyObject *args)
7863{
Victor Stinner8c62be82010-05-06 00:08:46 +00007864 int howMany;
7865 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007866
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 /* Read arguments */
7868 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7869 return NULL;
7870 if (howMany < 0)
7871 return PyErr_Format(PyExc_ValueError,
7872 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007873
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 /* Allocate bytes */
7875 result = PyBytes_FromStringAndSize(NULL, howMany);
7876 if (result != NULL) {
7877 /* Get random data */
7878 if (RAND_pseudo_bytes((unsigned char*)
7879 PyBytes_AS_STRING(result),
7880 howMany) < 0) {
7881 Py_DECREF(result);
7882 return PyErr_Format(PyExc_ValueError,
7883 "RAND_pseudo_bytes");
7884 }
7885 }
7886 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007887}
7888#endif
7889
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007890#ifdef HAVE_SETRESUID
7891PyDoc_STRVAR(posix_setresuid__doc__,
7892"setresuid(ruid, euid, suid)\n\n\
7893Set the current process's real, effective, and saved user ids.");
7894
7895static PyObject*
7896posix_setresuid (PyObject *self, PyObject *args)
7897{
Victor Stinner8c62be82010-05-06 00:08:46 +00007898 /* We assume uid_t is no larger than a long. */
7899 long ruid, euid, suid;
7900 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7901 return NULL;
7902 if (setresuid(ruid, euid, suid) < 0)
7903 return posix_error();
7904 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007905}
7906#endif
7907
7908#ifdef HAVE_SETRESGID
7909PyDoc_STRVAR(posix_setresgid__doc__,
7910"setresgid(rgid, egid, sgid)\n\n\
7911Set the current process's real, effective, and saved group ids.");
7912
7913static PyObject*
7914posix_setresgid (PyObject *self, PyObject *args)
7915{
Victor Stinner8c62be82010-05-06 00:08:46 +00007916 /* We assume uid_t is no larger than a long. */
7917 long rgid, egid, sgid;
7918 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7919 return NULL;
7920 if (setresgid(rgid, egid, sgid) < 0)
7921 return posix_error();
7922 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007923}
7924#endif
7925
7926#ifdef HAVE_GETRESUID
7927PyDoc_STRVAR(posix_getresuid__doc__,
7928"getresuid() -> (ruid, euid, suid)\n\n\
7929Get tuple of the current process's real, effective, and saved user ids.");
7930
7931static PyObject*
7932posix_getresuid (PyObject *self, PyObject *noargs)
7933{
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 uid_t ruid, euid, suid;
7935 long l_ruid, l_euid, l_suid;
7936 if (getresuid(&ruid, &euid, &suid) < 0)
7937 return posix_error();
7938 /* Force the values into long's as we don't know the size of uid_t. */
7939 l_ruid = ruid;
7940 l_euid = euid;
7941 l_suid = suid;
7942 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007943}
7944#endif
7945
7946#ifdef HAVE_GETRESGID
7947PyDoc_STRVAR(posix_getresgid__doc__,
7948"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007949Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007950
7951static PyObject*
7952posix_getresgid (PyObject *self, PyObject *noargs)
7953{
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 uid_t rgid, egid, sgid;
7955 long l_rgid, l_egid, l_sgid;
7956 if (getresgid(&rgid, &egid, &sgid) < 0)
7957 return posix_error();
7958 /* Force the values into long's as we don't know the size of uid_t. */
7959 l_rgid = rgid;
7960 l_egid = egid;
7961 l_sgid = sgid;
7962 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007963}
7964#endif
7965
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007966static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007968#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007970#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007972#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007974#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007976#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007978#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007979#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007981#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007982#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007984#endif /* HAVE_LCHMOD */
7985#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007987#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007988#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007990#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007991#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007993#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007994#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007995 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007996#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007997#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007998 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007999#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008000#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 {"getcwd", (PyCFunction)posix_getcwd_unicode,
8002 METH_NOARGS, posix_getcwd__doc__},
8003 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
8004 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008005#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008006#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008008#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00008009 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8010 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8011 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008012#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00008013 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008014#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008015#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00008016 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008017#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00008018#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00008019 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00008020#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00008021 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8022 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8023 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +00008025#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008027#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +00008028#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00008029 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +00008030 win_symlink__doc__},
8031#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008032#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008034#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008036#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008038#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8040 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8041 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008042#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00008043 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008044#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008046#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8048 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008049#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008050#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8052 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008053#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008054 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8055 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008056#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008057#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008058#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00008059 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008060#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008061#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008063#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008064#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008066#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008067#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008069#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008070#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008072#endif /* HAVE_GETEGID */
8073#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008074 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008075#endif /* HAVE_GETEUID */
8076#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008078#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008079#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00008080 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008081#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008083#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008085#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008086#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008087 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008088#endif /* HAVE_GETPPID */
8089#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008090 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008091#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008092#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008093 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008094#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008095#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00008096 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008097#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008098#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00008099 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008100#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008101#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008102 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008103#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00008104#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8106 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +00008107 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00008108#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008109#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008111#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008112#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008113 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008114#endif /* HAVE_SETEUID */
8115#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008116 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008117#endif /* HAVE_SETEGID */
8118#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008120#endif /* HAVE_SETREUID */
8121#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008123#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008124#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008125 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008126#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008127#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00008128 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008129#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00008130#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00008131 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00008132#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008133#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008134 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008135#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008136#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008137 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008138#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008139#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008141#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008142#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00008143 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008144#endif /* HAVE_WAIT3 */
8145#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008147#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008148#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008149 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008150#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008151#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008153#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008154#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008156#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008157#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008158 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008159#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008160#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008161 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008162#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008163#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00008164 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008165#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8167 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8168 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8169 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
8170 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8171 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8172 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8173 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8174 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008175#ifdef HAVE_SENDFILE
8176 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
8177 posix_sendfile__doc__},
8178#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008179 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8180 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008181#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008183#endif
8184#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008186#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008187#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008189#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008190#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00008191 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8192 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8193 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008194#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008195#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00008196 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008197#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008198#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008200#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008201#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008203#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008204 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008205#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00008206 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008207#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008208#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008209 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008210#endif
8211#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008212 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008213#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008214#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008215#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00008216 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008217#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008218#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008219 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008220#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008221#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00008222 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008223#endif /* WIFSTOPPED */
8224#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00008225 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008226#endif /* WIFSIGNALED */
8227#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00008228 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008229#endif /* WIFEXITED */
8230#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00008231 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008232#endif /* WEXITSTATUS */
8233#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008234 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008235#endif /* WTERMSIG */
8236#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008237 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008238#endif /* WSTOPSIG */
8239#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008240#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00008241 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008242#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00008243#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00008244 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008245#endif
Fred Drakec9680921999-12-13 16:37:25 +00008246#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008248#endif
8249#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008250 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008251#endif
8252#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008253 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008254#endif
8255#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008257#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008258 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008259#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008260 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00008261 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00008262 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00008263#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008264#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008266#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008267 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008268 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008269 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008270 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00008271 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008272 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008273#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008274 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008275#endif
8276#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008277 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008278#endif
8279#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008280 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008281#endif
8282#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008283 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008284#endif
8285
Victor Stinner8c62be82010-05-06 00:08:46 +00008286 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008287};
8288
8289
Barry Warsaw4a342091996-12-19 23:50:02 +00008290static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008291ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008292{
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008294}
8295
Guido van Rossumd48f2521997-12-05 22:19:34 +00008296#if defined(PYOS_OS2)
8297/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008298static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008299{
8300 APIRET rc;
8301 ULONG values[QSV_MAX+1];
8302 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008303 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008304
8305 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008306 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008307 Py_END_ALLOW_THREADS
8308
8309 if (rc != NO_ERROR) {
8310 os2_error(rc);
8311 return -1;
8312 }
8313
Fred Drake4d1e64b2002-04-15 19:40:07 +00008314 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8315 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8316 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8317 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8318 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8319 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8320 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008321
8322 switch (values[QSV_VERSION_MINOR]) {
8323 case 0: ver = "2.00"; break;
8324 case 10: ver = "2.10"; break;
8325 case 11: ver = "2.11"; break;
8326 case 30: ver = "3.00"; break;
8327 case 40: ver = "4.00"; break;
8328 case 50: ver = "5.00"; break;
8329 default:
Tim Peters885d4572001-11-28 20:27:42 +00008330 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008332 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008333 ver = &tmp[0];
8334 }
8335
8336 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008337 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008338 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008339
8340 /* Add Indicator of Which Drive was Used to Boot the System */
8341 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8342 tmp[1] = ':';
8343 tmp[2] = '\0';
8344
Fred Drake4d1e64b2002-04-15 19:40:07 +00008345 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008346}
8347#endif
8348
Brian Curtin52173d42010-12-02 18:29:18 +00008349#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00008350static int
Brian Curtin52173d42010-12-02 18:29:18 +00008351enable_symlink()
8352{
8353 HANDLE tok;
8354 TOKEN_PRIVILEGES tok_priv;
8355 LUID luid;
8356 int meth_idx = 0;
8357
8358 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008359 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008360
8361 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008362 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008363
8364 tok_priv.PrivilegeCount = 1;
8365 tok_priv.Privileges[0].Luid = luid;
8366 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
8367
8368 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
8369 sizeof(TOKEN_PRIVILEGES),
8370 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +00008371 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +00008372
Brian Curtin3b4499c2010-12-28 14:31:47 +00008373 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
8374 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +00008375}
8376#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
8377
Barry Warsaw4a342091996-12-19 23:50:02 +00008378static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008379all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008380{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008381#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008382 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008383#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008384#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008385 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008386#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008387#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008388 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008389#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008390#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008391 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008392#endif
Fred Drakec9680921999-12-13 16:37:25 +00008393#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008394 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008395#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008396#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008398#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008399#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008401#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008402#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008404#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008405#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008406 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008407#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008408#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008410#endif
8411#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008412 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008413#endif
8414#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008415 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008416#endif
8417#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008419#endif
8420#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008421 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008422#endif
8423#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008425#endif
8426#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008427 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008428#endif
8429#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008430 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008431#endif
8432#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008433 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008434#endif
8435#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008437#endif
8438#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008440#endif
8441#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008442 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008443#endif
8444#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008446#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008447#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008448 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008449#endif
8450#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008452#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008453#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008454 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008455#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008456#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008457 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008458#endif
8459#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008460 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008461#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008462
Tim Peters5aa91602002-01-30 05:46:57 +00008463/* MS Windows */
8464#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008465 /* Don't inherit in child processes. */
8466 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008467#endif
8468#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 /* Optimize for short life (keep in memory). */
8470 /* MS forgot to define this one with a non-underscore form too. */
8471 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008472#endif
8473#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008474 /* Automatically delete when last handle is closed. */
8475 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008476#endif
8477#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008478 /* Optimize for random access. */
8479 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008480#endif
8481#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 /* Optimize for sequential access. */
8483 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008484#endif
8485
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008486/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008487#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008488 /* Send a SIGIO signal whenever input or output
8489 becomes available on file descriptor */
8490 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008491#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008492#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 /* Direct disk access. */
8494 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008495#endif
8496#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008497 /* Must be a directory. */
8498 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008499#endif
8500#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008501 /* Do not follow links. */
8502 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008503#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008504#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 /* Do not update the access time. */
8506 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008507#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008508
Victor Stinner8c62be82010-05-06 00:08:46 +00008509 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008510#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008512#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008513#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008515#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008516#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008517 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008518#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008519#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008521#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008522#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008523 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008524#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008525#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008526 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008527#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008528#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008530#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008531#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008532 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008533#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008534#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008536#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008537#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008538 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008539#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008540#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008541 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008542#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008543#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008544 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008545#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008546#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008547 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008548#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008549#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008550 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008551#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008552#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008553 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008554#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008555#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008556 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008557#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008558#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008559 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008560#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008561
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008562 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008563#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008564 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008565#endif /* ST_RDONLY */
8566#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008567 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008568#endif /* ST_NOSUID */
8569
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008570 /* FreeBSD sendfile() constants */
8571#ifdef SF_NODISKIO
8572 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
8573#endif
8574#ifdef SF_MNOWAIT
8575 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
8576#endif
8577#ifdef SF_SYNC
8578 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
8579#endif
8580
Guido van Rossum246bc171999-02-01 23:54:31 +00008581#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008582#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008583 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8584 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8585 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8586 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8587 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8588 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8589 if (ins(d, "P_PM", (long)P_PM)) return -1;
8590 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8591 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8592 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8593 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8594 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8595 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8596 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8597 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8598 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8599 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8600 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8601 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8602 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008603#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008604 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8605 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8606 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8607 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8608 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008609#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008610#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008611
Guido van Rossumd48f2521997-12-05 22:19:34 +00008612#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008613 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008614#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008615 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008616}
8617
8618
Tim Peters5aa91602002-01-30 05:46:57 +00008619#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008620#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008621#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008622
8623#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008624#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008625#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008626
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008627#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008628#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008629#define MODNAME "posix"
8630#endif
8631
Martin v. Löwis1a214512008-06-11 05:26:20 +00008632static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008633 PyModuleDef_HEAD_INIT,
8634 MODNAME,
8635 posix__doc__,
8636 -1,
8637 posix_methods,
8638 NULL,
8639 NULL,
8640 NULL,
8641 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008642};
8643
8644
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008645PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008646INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008647{
Victor Stinner8c62be82010-05-06 00:08:46 +00008648 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008649
Brian Curtin52173d42010-12-02 18:29:18 +00008650#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +00008651 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +00008652#endif
8653
Victor Stinner8c62be82010-05-06 00:08:46 +00008654 m = PyModule_Create(&posixmodule);
8655 if (m == NULL)
8656 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008657
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 /* Initialize environ dictionary */
8659 v = convertenviron();
8660 Py_XINCREF(v);
8661 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8662 return NULL;
8663 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008664
Victor Stinner8c62be82010-05-06 00:08:46 +00008665 if (all_ins(m))
8666 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008667
Victor Stinner8c62be82010-05-06 00:08:46 +00008668 if (setup_confname_tables(m))
8669 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008670
Victor Stinner8c62be82010-05-06 00:08:46 +00008671 Py_INCREF(PyExc_OSError);
8672 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008673
Guido van Rossumb3d39562000-01-31 18:41:26 +00008674#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008675 if (posix_putenv_garbage == NULL)
8676 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008677#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008678
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 if (!initialized) {
8680 stat_result_desc.name = MODNAME ".stat_result";
8681 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8682 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8683 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8684 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8685 structseq_new = StatResultType.tp_new;
8686 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008687
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 statvfs_result_desc.name = MODNAME ".statvfs_result";
8689 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008690#ifdef NEED_TICKS_PER_SECOND
8691# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008692 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008693# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008695# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008696 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008697# endif
8698#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008699 }
8700 Py_INCREF((PyObject*) &StatResultType);
8701 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8702 Py_INCREF((PyObject*) &StatVFSResultType);
8703 PyModule_AddObject(m, "statvfs_result",
8704 (PyObject*) &StatVFSResultType);
8705 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008706
8707#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008708 /*
8709 * Step 2 of weak-linking support on Mac OS X.
8710 *
8711 * The code below removes functions that are not available on the
8712 * currently active platform.
8713 *
8714 * This block allow one to use a python binary that was build on
8715 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8716 * OSX 10.4.
8717 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008718#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008719 if (fstatvfs == NULL) {
8720 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8721 return NULL;
8722 }
8723 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008724#endif /* HAVE_FSTATVFS */
8725
8726#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 if (statvfs == NULL) {
8728 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8729 return NULL;
8730 }
8731 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008732#endif /* HAVE_STATVFS */
8733
8734# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008735 if (lchown == NULL) {
8736 if (PyObject_DelAttrString(m, "lchown") == -1) {
8737 return NULL;
8738 }
8739 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008740#endif /* HAVE_LCHOWN */
8741
8742
8743#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008744 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008745
Guido van Rossumb6775db1994-08-01 11:34:53 +00008746}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008747
8748#ifdef __cplusplus
8749}
8750#endif