blob: 9012e3979401fb4bb207d28c3dee3de5fe0f4635 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson9428d532011-09-14 11:45:52 -0400110#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
111#define USE_XATTRS
112#endif
113
114#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400115#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400116#endif
117
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
119#ifdef HAVE_SYS_SOCKET_H
120#include <sys/socket.h>
121#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#endif
123
Victor Stinner8b905bd2011-10-25 13:34:04 +0200124#ifdef HAVE_DLFCN_H
125#include <dlfcn.h>
126#endif
127
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000129/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000131#include <process.h>
132#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#define HAVE_GETCWD 1
135#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#if defined(__OS2__)
138#define HAVE_EXECV 1
139#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#include <process.h>
142#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000143#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#define HAVE_EXECV 1
145#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_WAIT 1
150#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000152#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000153#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000154#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#define HAVE_EXECV 1
157#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#define HAVE_SYSTEM 1
159#define HAVE_CWAIT 1
160#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000161#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000162#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000163#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
164/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166/* Unix functions that the configure script doesn't check for */
167#define HAVE_EXECV 1
168#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000170#define HAVE_FORK1 1
171#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_GETCWD 1
173#define HAVE_GETEGID 1
174#define HAVE_GETEUID 1
175#define HAVE_GETGID 1
176#define HAVE_GETPPID 1
177#define HAVE_GETUID 1
178#define HAVE_KILL 1
179#define HAVE_OPENDIR 1
180#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000183#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000184#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#endif /* _MSC_VER */
186#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000187#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000189
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000191
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000192#if defined(__sgi)&&_COMPILER_VERSION>=700
193/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
194 (default) */
195extern char *ctermid_r(char *);
196#endif
197
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000198#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000199#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000201#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000202#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000207#endif
208#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int chdir(char *);
210extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chdir(const char *);
213extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000214#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000215#ifdef __BORLANDC__
216extern int chmod(const char *, int);
217#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000219#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000220/*#ifdef HAVE_FCHMOD
221extern int fchmod(int, mode_t);
222#endif*/
223/*#ifdef HAVE_LCHMOD
224extern int lchmod(const char *, mode_t);
225#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000226extern int chown(const char *, uid_t, gid_t);
227extern char *getcwd(char *, int);
228extern char *strerror(int);
229extern int link(const char *, const char *);
230extern int rename(const char *, const char *);
231extern int stat(const char *, struct stat *);
232extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000235#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000240
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000241#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#ifdef HAVE_UTIME_H
244#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000245#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000247#ifdef HAVE_SYS_UTIME_H
248#include <sys/utime.h>
249#define HAVE_UTIME_H /* pretend we do for the rest of this file */
250#endif /* HAVE_SYS_UTIME_H */
251
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#ifdef HAVE_SYS_TIMES_H
253#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000254#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
256#ifdef HAVE_SYS_PARAM_H
257#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000258#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259
260#ifdef HAVE_SYS_UTSNAME_H
261#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000264#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000266#define NAMLEN(dirent) strlen((dirent)->d_name)
267#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000268#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#include <direct.h>
270#define NAMLEN(dirent) strlen((dirent)->d_name)
271#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000273#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000275#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000276#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000277#endif
278#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#endif
281#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#endif
284#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000286#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000287#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000289#endif
290#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#endif
293#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000296#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000297#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000298#endif
299#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000300#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#endif
302#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000305#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000306#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000307#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000308#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000309#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000310#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
311#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000312static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000313#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000314#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000315
Guido van Rossumd48f2521997-12-05 22:19:34 +0000316#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000317#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000318#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319
Tim Petersbc2e10e2002-03-03 23:17:02 +0000320#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000321#if defined(PATH_MAX) && PATH_MAX > 1024
322#define MAXPATHLEN PATH_MAX
323#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000326#endif /* MAXPATHLEN */
327
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000328#ifdef UNION_WAIT
329/* Emulate some macros on systems that have a union instead of macros */
330
331#ifndef WIFEXITED
332#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
333#endif
334
335#ifndef WEXITSTATUS
336#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
337#endif
338
339#ifndef WTERMSIG
340#define WTERMSIG(u_wait) ((u_wait).w_termsig)
341#endif
342
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000343#define WAIT_TYPE union wait
344#define WAIT_STATUS_INT(s) (s.w_status)
345
346#else /* !UNION_WAIT */
347#define WAIT_TYPE int
348#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000349#endif /* UNION_WAIT */
350
Greg Wardb48bc172000-03-01 21:51:56 +0000351/* Don't use the "_r" form if we don't need it (also, won't have a
352 prototype for it, at least on Solaris -- maybe others as well?). */
353#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
354#define USE_CTERMID_R
355#endif
356
Fred Drake699f3522000-06-29 21:12:41 +0000357/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000358#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000359#undef FSTAT
360#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000361#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000362# define STAT win32_stat
363# define FSTAT win32_fstat
364# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000365#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000366# define STAT stat
367# define FSTAT fstat
368# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000369#endif
370
Tim Peters11b23062003-04-23 02:39:17 +0000371#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#include <sys/mkdev.h>
373#else
374#if defined(MAJOR_IN_SYSMACROS)
375#include <sys/sysmacros.h>
376#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000377#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
378#include <sys/mkdev.h>
379#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000380#endif
Fred Drake699f3522000-06-29 21:12:41 +0000381
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200382/* A helper used by a number of POSIX-only functions */
383#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000384static int
385_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000386{
387#if !defined(HAVE_LARGEFILE_SUPPORT)
388 *((off_t*)addr) = PyLong_AsLong(arg);
389#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000390 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000391#endif
392 if (PyErr_Occurred())
393 return 0;
394 return 1;
395}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200396#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000397
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000398#if defined _MSC_VER && _MSC_VER >= 1400
399/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
400 * valid and throw an assertion if it isn't.
401 * Normally, an invalid fd is likely to be a C program error and therefore
402 * an assertion can be useful, but it does contradict the POSIX standard
403 * which for write(2) states:
404 * "Otherwise, -1 shall be returned and errno set to indicate the error."
405 * "[EBADF] The fildes argument is not a valid file descriptor open for
406 * writing."
407 * Furthermore, python allows the user to enter any old integer
408 * as a fd and should merely raise a python exception on error.
409 * The Microsoft CRT doesn't provide an official way to check for the
410 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000411 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000412 * internal structures involved.
413 * The structures below must be updated for each version of visual studio
414 * according to the file internal.h in the CRT source, until MS comes
415 * up with a less hacky way to do this.
416 * (all of this is to avoid globally modifying the CRT behaviour using
417 * _set_invalid_parameter_handler() and _CrtSetReportMode())
418 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000419/* The actual size of the structure is determined at runtime.
420 * Only the first items must be present.
421 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000422typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000423 intptr_t osfhnd;
424 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000425} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000426
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000427extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000428#define IOINFO_L2E 5
429#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
430#define IOINFO_ARRAYS 64
431#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
432#define FOPEN 0x01
433#define _NO_CONSOLE_FILENO (intptr_t)-2
434
435/* This function emulates what the windows CRT does to validate file handles */
436int
437_PyVerify_fd(int fd)
438{
Victor Stinner8c62be82010-05-06 00:08:46 +0000439 const int i1 = fd >> IOINFO_L2E;
440 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000441
Antoine Pitrou22e41552010-08-15 18:07:50 +0000442 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000443
Victor Stinner8c62be82010-05-06 00:08:46 +0000444 /* Determine the actual size of the ioinfo structure,
445 * as used by the CRT loaded in memory
446 */
447 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
448 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
449 }
450 if (sizeof_ioinfo == 0) {
451 /* This should not happen... */
452 goto fail;
453 }
454
455 /* See that it isn't a special CLEAR fileno */
456 if (fd != _NO_CONSOLE_FILENO) {
457 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
458 * we check pointer validity and other info
459 */
460 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
461 /* finally, check that the file is open */
462 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
463 if (info->osfile & FOPEN) {
464 return 1;
465 }
466 }
467 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000468 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000469 errno = EBADF;
470 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000471}
472
473/* the special case of checking dup2. The target fd must be in a sensible range */
474static int
475_PyVerify_fd_dup2(int fd1, int fd2)
476{
Victor Stinner8c62be82010-05-06 00:08:46 +0000477 if (!_PyVerify_fd(fd1))
478 return 0;
479 if (fd2 == _NO_CONSOLE_FILENO)
480 return 0;
481 if ((unsigned)fd2 < _NHANDLE_)
482 return 1;
483 else
484 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000485}
486#else
487/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
488#define _PyVerify_fd_dup2(A, B) (1)
489#endif
490
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000491#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000492/* The following structure was copied from
493 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
494 include doesn't seem to be present in the Windows SDK (at least as included
495 with Visual Studio Express). */
496typedef struct _REPARSE_DATA_BUFFER {
497 ULONG ReparseTag;
498 USHORT ReparseDataLength;
499 USHORT Reserved;
500 union {
501 struct {
502 USHORT SubstituteNameOffset;
503 USHORT SubstituteNameLength;
504 USHORT PrintNameOffset;
505 USHORT PrintNameLength;
506 ULONG Flags;
507 WCHAR PathBuffer[1];
508 } SymbolicLinkReparseBuffer;
509
510 struct {
511 USHORT SubstituteNameOffset;
512 USHORT SubstituteNameLength;
513 USHORT PrintNameOffset;
514 USHORT PrintNameLength;
515 WCHAR PathBuffer[1];
516 } MountPointReparseBuffer;
517
518 struct {
519 UCHAR DataBuffer[1];
520 } GenericReparseBuffer;
521 };
522} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
523
524#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
525 GenericReparseBuffer)
526#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
527
528static int
Brian Curtind25aef52011-06-13 15:16:04 -0500529win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000530{
531 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
532 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
533 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000534
535 if (0 == DeviceIoControl(
536 reparse_point_handle,
537 FSCTL_GET_REPARSE_POINT,
538 NULL, 0, /* in buffer */
539 target_buffer, sizeof(target_buffer),
540 &n_bytes_returned,
541 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500542 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000543
544 if (reparse_tag)
545 *reparse_tag = rdb->ReparseTag;
546
Brian Curtind25aef52011-06-13 15:16:04 -0500547 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000548}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100549
550static int
551win32_warn_bytes_api()
552{
553 return PyErr_WarnEx(PyExc_DeprecationWarning,
554 "The Windows bytes API has been deprecated, "
555 "use Unicode filenames instead",
556 1);
557}
558
559static PyObject*
560win32_decode_filename(PyObject *obj)
561{
562 PyObject *unicode;
563 if (PyUnicode_Check(obj)) {
564 if (PyUnicode_READY(obj))
565 return NULL;
566 Py_INCREF(obj);
567 return obj;
568 }
569 if (!PyUnicode_FSDecoder(obj, &unicode))
570 return NULL;
571 if (win32_warn_bytes_api()) {
572 Py_DECREF(unicode);
573 return NULL;
574 }
575 return unicode;
576}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000577#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000578
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000579/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000580#ifdef WITH_NEXT_FRAMEWORK
581/* On Darwin/MacOSX a shared library or framework has no access to
582** environ directly, we must obtain it with _NSGetEnviron().
583*/
584#include <crt_externs.h>
585static char **environ;
586#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000587extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000588#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000589
Barry Warsaw53699e91996-12-10 23:23:01 +0000590static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000591convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000592{
Victor Stinner8c62be82010-05-06 00:08:46 +0000593 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000594#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000595 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000596#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000597 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000598#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000599#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000600 APIRET rc;
601 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
602#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000603
Victor Stinner8c62be82010-05-06 00:08:46 +0000604 d = PyDict_New();
605 if (d == NULL)
606 return NULL;
607#ifdef WITH_NEXT_FRAMEWORK
608 if (environ == NULL)
609 environ = *_NSGetEnviron();
610#endif
611#ifdef MS_WINDOWS
612 /* _wenviron must be initialized in this way if the program is started
613 through main() instead of wmain(). */
614 _wgetenv(L"");
615 if (_wenviron == NULL)
616 return d;
617 /* This part ignores errors */
618 for (e = _wenviron; *e != NULL; e++) {
619 PyObject *k;
620 PyObject *v;
621 wchar_t *p = wcschr(*e, L'=');
622 if (p == NULL)
623 continue;
624 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
625 if (k == NULL) {
626 PyErr_Clear();
627 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000628 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000629 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
630 if (v == NULL) {
631 PyErr_Clear();
632 Py_DECREF(k);
633 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000634 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000635 if (PyDict_GetItem(d, k) == NULL) {
636 if (PyDict_SetItem(d, k, v) != 0)
637 PyErr_Clear();
638 }
639 Py_DECREF(k);
640 Py_DECREF(v);
641 }
642#else
643 if (environ == NULL)
644 return d;
645 /* This part ignores errors */
646 for (e = environ; *e != NULL; e++) {
647 PyObject *k;
648 PyObject *v;
649 char *p = strchr(*e, '=');
650 if (p == NULL)
651 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000652 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000653 if (k == NULL) {
654 PyErr_Clear();
655 continue;
656 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000657 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000658 if (v == NULL) {
659 PyErr_Clear();
660 Py_DECREF(k);
661 continue;
662 }
663 if (PyDict_GetItem(d, k) == NULL) {
664 if (PyDict_SetItem(d, k, v) != 0)
665 PyErr_Clear();
666 }
667 Py_DECREF(k);
668 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000669 }
670#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000671#if defined(PYOS_OS2)
672 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
673 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
674 PyObject *v = PyBytes_FromString(buffer);
675 PyDict_SetItemString(d, "BEGINLIBPATH", v);
676 Py_DECREF(v);
677 }
678 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
679 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
680 PyObject *v = PyBytes_FromString(buffer);
681 PyDict_SetItemString(d, "ENDLIBPATH", v);
682 Py_DECREF(v);
683 }
684#endif
685 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686}
687
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000688/* Set a POSIX-specific error from errno, and return NULL */
689
Barry Warsawd58d7641998-07-23 16:14:40 +0000690static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000691posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000692{
Victor Stinner8c62be82010-05-06 00:08:46 +0000693 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694}
Barry Warsawd58d7641998-07-23 16:14:40 +0000695static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000696posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000697{
Victor Stinner8c62be82010-05-06 00:08:46 +0000698 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000699}
700
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000701
Mark Hammondef8b6542001-05-13 08:04:26 +0000702static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000703posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000704{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000705 PyObject *name_str, *rc;
706 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
707 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000708 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000709 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
710 name_str);
711 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000712 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000713}
714
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000715#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000716static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000717win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000718{
Victor Stinner8c62be82010-05-06 00:08:46 +0000719 /* XXX We should pass the function name along in the future.
720 (winreg.c also wants to pass the function name.)
721 This would however require an additional param to the
722 Windows error object, which is non-trivial.
723 */
724 errno = GetLastError();
725 if (filename)
726 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
727 else
728 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000729}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000730
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000731static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +0200732win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000733{
Victor Stinner8c62be82010-05-06 00:08:46 +0000734 /* XXX - see win32_error for comments on 'function' */
735 errno = GetLastError();
736 if (filename)
737 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
738 else
739 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000740}
741
Victor Stinnereb5657a2011-09-30 01:44:27 +0200742static PyObject *
743win32_error_object(char* function, PyObject* filename)
744{
745 /* XXX - see win32_error for comments on 'function' */
746 errno = GetLastError();
747 if (filename)
748 return PyErr_SetExcFromWindowsErrWithFilenameObject(
749 PyExc_WindowsError,
750 errno,
751 filename);
752 else
753 return PyErr_SetFromWindowsErr(errno);
754}
755
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000756#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000757
Guido van Rossumd48f2521997-12-05 22:19:34 +0000758#if defined(PYOS_OS2)
759/**********************************************************************
760 * Helper Function to Trim and Format OS/2 Messages
761 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000762static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000763os2_formatmsg(char *msgbuf, int msglen, char *reason)
764{
765 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
766
767 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
768 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
769
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000770 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000771 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
772 }
773
774 /* Add Optional Reason Text */
775 if (reason) {
776 strcat(msgbuf, " : ");
777 strcat(msgbuf, reason);
778 }
779}
780
781/**********************************************************************
782 * Decode an OS/2 Operating System Error Code
783 *
784 * A convenience function to lookup an OS/2 error code and return a
785 * text message we can use to raise a Python exception.
786 *
787 * Notes:
788 * The messages for errors returned from the OS/2 kernel reside in
789 * the file OSO001.MSG in the \OS2 directory hierarchy.
790 *
791 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000792static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000793os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
794{
795 APIRET rc;
796 ULONG msglen;
797
798 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
799 Py_BEGIN_ALLOW_THREADS
800 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
801 errorcode, "oso001.msg", &msglen);
802 Py_END_ALLOW_THREADS
803
804 if (rc == NO_ERROR)
805 os2_formatmsg(msgbuf, msglen, reason);
806 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000807 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000808 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000809
810 return msgbuf;
811}
812
813/* Set an OS/2-specific error and return NULL. OS/2 kernel
814 errors are not in a global variable e.g. 'errno' nor are
815 they congruent with posix error numbers. */
816
Victor Stinner8c62be82010-05-06 00:08:46 +0000817static PyObject *
818os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000819{
820 char text[1024];
821 PyObject *v;
822
823 os2_strerror(text, sizeof(text), code, "");
824
825 v = Py_BuildValue("(is)", code, text);
826 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000827 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000828 Py_DECREF(v);
829 }
830 return NULL; /* Signal to Python that an Exception is Pending */
831}
832
833#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000834
835/* POSIX generic methods */
836
Barry Warsaw53699e91996-12-10 23:23:01 +0000837static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000838posix_fildes(PyObject *fdobj, int (*func)(int))
839{
Victor Stinner8c62be82010-05-06 00:08:46 +0000840 int fd;
841 int res;
842 fd = PyObject_AsFileDescriptor(fdobj);
843 if (fd < 0)
844 return NULL;
845 if (!_PyVerify_fd(fd))
846 return posix_error();
847 Py_BEGIN_ALLOW_THREADS
848 res = (*func)(fd);
849 Py_END_ALLOW_THREADS
850 if (res < 0)
851 return posix_error();
852 Py_INCREF(Py_None);
853 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000854}
Guido van Rossum21142a01999-01-08 21:05:37 +0000855
856static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000857posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000858{
Victor Stinner8c62be82010-05-06 00:08:46 +0000859 PyObject *opath1 = NULL;
860 char *path1;
861 int res;
862 if (!PyArg_ParseTuple(args, format,
863 PyUnicode_FSConverter, &opath1))
864 return NULL;
865 path1 = PyBytes_AsString(opath1);
866 Py_BEGIN_ALLOW_THREADS
867 res = (*func)(path1);
868 Py_END_ALLOW_THREADS
869 if (res < 0)
870 return posix_error_with_allocated_filename(opath1);
871 Py_DECREF(opath1);
872 Py_INCREF(Py_None);
873 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000874}
875
Barry Warsaw53699e91996-12-10 23:23:01 +0000876static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000877posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000878 char *format,
879 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000880{
Victor Stinner8c62be82010-05-06 00:08:46 +0000881 PyObject *opath1 = NULL, *opath2 = NULL;
882 char *path1, *path2;
883 int res;
884 if (!PyArg_ParseTuple(args, format,
885 PyUnicode_FSConverter, &opath1,
886 PyUnicode_FSConverter, &opath2)) {
887 return NULL;
888 }
889 path1 = PyBytes_AsString(opath1);
890 path2 = PyBytes_AsString(opath2);
891 Py_BEGIN_ALLOW_THREADS
892 res = (*func)(path1, path2);
893 Py_END_ALLOW_THREADS
894 Py_DECREF(opath1);
895 Py_DECREF(opath2);
896 if (res != 0)
897 /* XXX how to report both path1 and path2??? */
898 return posix_error();
899 Py_INCREF(Py_None);
900 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000901}
902
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000903#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000904static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000905win32_1str(PyObject* args, char* func,
906 char* format, BOOL (__stdcall *funcA)(LPCSTR),
907 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000908{
Victor Stinner8c62be82010-05-06 00:08:46 +0000909 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100910 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +0000911 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000912
Victor Stinnereb5657a2011-09-30 01:44:27 +0200913 if (PyArg_ParseTuple(args, wformat, &uni))
914 {
915 wchar_t *wstr = PyUnicode_AsUnicode(uni);
916 if (wstr == NULL)
917 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000918 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +0200919 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +0000920 Py_END_ALLOW_THREADS
921 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +0200922 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +0000923 Py_INCREF(Py_None);
924 return Py_None;
925 }
Victor Stinnereb5657a2011-09-30 01:44:27 +0200926 PyErr_Clear();
927
Victor Stinner8c62be82010-05-06 00:08:46 +0000928 if (!PyArg_ParseTuple(args, format, &ansi))
929 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100930 if (win32_warn_bytes_api())
931 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000932 Py_BEGIN_ALLOW_THREADS
933 result = funcA(ansi);
934 Py_END_ALLOW_THREADS
935 if (!result)
936 return win32_error(func, ansi);
937 Py_INCREF(Py_None);
938 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000939
940}
941
942/* This is a reimplementation of the C library's chdir function,
943 but one that produces Win32 errors instead of DOS error codes.
944 chdir is essentially a wrapper around SetCurrentDirectory; however,
945 it also needs to set "magic" environment variables indicating
946 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000947static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000948win32_chdir(LPCSTR path)
949{
Victor Stinner8c62be82010-05-06 00:08:46 +0000950 char new_path[MAX_PATH+1];
951 int result;
952 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000953
Victor Stinner8c62be82010-05-06 00:08:46 +0000954 if(!SetCurrentDirectoryA(path))
955 return FALSE;
956 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
957 if (!result)
958 return FALSE;
959 /* In the ANSI API, there should not be any paths longer
960 than MAX_PATH. */
961 assert(result <= MAX_PATH+1);
962 if (strncmp(new_path, "\\\\", 2) == 0 ||
963 strncmp(new_path, "//", 2) == 0)
964 /* UNC path, nothing to do. */
965 return TRUE;
966 env[1] = new_path[0];
967 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000968}
969
970/* The Unicode version differs from the ANSI version
971 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000972static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000973win32_wchdir(LPCWSTR path)
974{
Victor Stinner8c62be82010-05-06 00:08:46 +0000975 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
976 int result;
977 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000978
Victor Stinner8c62be82010-05-06 00:08:46 +0000979 if(!SetCurrentDirectoryW(path))
980 return FALSE;
981 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
982 if (!result)
983 return FALSE;
984 if (result > MAX_PATH+1) {
985 new_path = malloc(result * sizeof(wchar_t));
986 if (!new_path) {
987 SetLastError(ERROR_OUTOFMEMORY);
988 return FALSE;
989 }
990 result = GetCurrentDirectoryW(result, new_path);
991 if (!result) {
992 free(new_path);
993 return FALSE;
994 }
995 }
996 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
997 wcsncmp(new_path, L"//", 2) == 0)
998 /* UNC path, nothing to do. */
999 return TRUE;
1000 env[1] = new_path[0];
1001 result = SetEnvironmentVariableW(env, new_path);
1002 if (new_path != _new_path)
1003 free(new_path);
1004 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001005}
1006#endif
1007
Martin v. Löwis14694662006-02-03 12:54:16 +00001008#ifdef MS_WINDOWS
1009/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1010 - time stamps are restricted to second resolution
1011 - file modification times suffer from forth-and-back conversions between
1012 UTC and local time
1013 Therefore, we implement our own stat, based on the Win32 API directly.
1014*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001015#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001016
1017struct win32_stat{
1018 int st_dev;
1019 __int64 st_ino;
1020 unsigned short st_mode;
1021 int st_nlink;
1022 int st_uid;
1023 int st_gid;
1024 int st_rdev;
1025 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001026 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001027 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001028 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001029 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001030 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001031 int st_ctime_nsec;
1032};
1033
1034static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1035
1036static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001037FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001038{
Victor Stinner8c62be82010-05-06 00:08:46 +00001039 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1040 /* Cannot simply cast and dereference in_ptr,
1041 since it might not be aligned properly */
1042 __int64 in;
1043 memcpy(&in, in_ptr, sizeof(in));
1044 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001045 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001046}
1047
Thomas Wouters477c8d52006-05-27 19:21:47 +00001048static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001049time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001050{
Victor Stinner8c62be82010-05-06 00:08:46 +00001051 /* XXX endianness */
1052 __int64 out;
1053 out = time_in + secs_between_epochs;
1054 out = out * 10000000 + nsec_in / 100;
1055 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001056}
1057
Martin v. Löwis14694662006-02-03 12:54:16 +00001058/* Below, we *know* that ugo+r is 0444 */
1059#if _S_IREAD != 0400
1060#error Unsupported C library
1061#endif
1062static int
1063attributes_to_mode(DWORD attr)
1064{
Victor Stinner8c62be82010-05-06 00:08:46 +00001065 int m = 0;
1066 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1067 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1068 else
1069 m |= _S_IFREG;
1070 if (attr & FILE_ATTRIBUTE_READONLY)
1071 m |= 0444;
1072 else
1073 m |= 0666;
1074 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001075}
1076
1077static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001078attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001079{
Victor Stinner8c62be82010-05-06 00:08:46 +00001080 memset(result, 0, sizeof(*result));
1081 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1082 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1083 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1084 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1085 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001086 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001087 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001088 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1089 /* first clear the S_IFMT bits */
1090 result->st_mode ^= (result->st_mode & 0170000);
1091 /* now set the bits that make this a symlink */
1092 result->st_mode |= 0120000;
1093 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001094
Victor Stinner8c62be82010-05-06 00:08:46 +00001095 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001096}
1097
Guido van Rossumd8faa362007-04-27 19:54:29 +00001098static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001099attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001100{
Victor Stinner8c62be82010-05-06 00:08:46 +00001101 HANDLE hFindFile;
1102 WIN32_FIND_DATAA FileData;
1103 hFindFile = FindFirstFileA(pszFile, &FileData);
1104 if (hFindFile == INVALID_HANDLE_VALUE)
1105 return FALSE;
1106 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001107 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001108 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001109 info->dwFileAttributes = FileData.dwFileAttributes;
1110 info->ftCreationTime = FileData.ftCreationTime;
1111 info->ftLastAccessTime = FileData.ftLastAccessTime;
1112 info->ftLastWriteTime = FileData.ftLastWriteTime;
1113 info->nFileSizeHigh = FileData.nFileSizeHigh;
1114 info->nFileSizeLow = FileData.nFileSizeLow;
1115/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001116 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1117 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001118 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001119}
1120
1121static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001122attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001123{
Victor Stinner8c62be82010-05-06 00:08:46 +00001124 HANDLE hFindFile;
1125 WIN32_FIND_DATAW FileData;
1126 hFindFile = FindFirstFileW(pszFile, &FileData);
1127 if (hFindFile == INVALID_HANDLE_VALUE)
1128 return FALSE;
1129 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001130 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001131 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001132 info->dwFileAttributes = FileData.dwFileAttributes;
1133 info->ftCreationTime = FileData.ftCreationTime;
1134 info->ftLastAccessTime = FileData.ftLastAccessTime;
1135 info->ftLastWriteTime = FileData.ftLastWriteTime;
1136 info->nFileSizeHigh = FileData.nFileSizeHigh;
1137 info->nFileSizeLow = FileData.nFileSizeLow;
1138/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001139 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1140 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001141 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001142}
1143
Brian Curtind25aef52011-06-13 15:16:04 -05001144/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1145static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001146static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1147 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001148static int
Brian Curtind25aef52011-06-13 15:16:04 -05001149check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001150{
Brian Curtind25aef52011-06-13 15:16:04 -05001151 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001152 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1153 DWORD);
1154
Brian Curtind25aef52011-06-13 15:16:04 -05001155 /* only recheck */
1156 if (!has_GetFinalPathNameByHandle)
1157 {
1158 hKernel32 = GetModuleHandle("KERNEL32");
1159 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1160 "GetFinalPathNameByHandleA");
1161 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1162 "GetFinalPathNameByHandleW");
1163 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1164 Py_GetFinalPathNameByHandleW;
1165 }
1166 return has_GetFinalPathNameByHandle;
1167}
1168
1169static BOOL
1170get_target_path(HANDLE hdl, wchar_t **target_path)
1171{
1172 int buf_size, result_length;
1173 wchar_t *buf;
1174
1175 /* We have a good handle to the target, use it to determine
1176 the target path name (then we'll call lstat on it). */
1177 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1178 VOLUME_NAME_DOS);
1179 if(!buf_size)
1180 return FALSE;
1181
1182 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001183 if (!buf) {
1184 SetLastError(ERROR_OUTOFMEMORY);
1185 return FALSE;
1186 }
1187
Brian Curtind25aef52011-06-13 15:16:04 -05001188 result_length = Py_GetFinalPathNameByHandleW(hdl,
1189 buf, buf_size, VOLUME_NAME_DOS);
1190
1191 if(!result_length) {
1192 free(buf);
1193 return FALSE;
1194 }
1195
1196 if(!CloseHandle(hdl)) {
1197 free(buf);
1198 return FALSE;
1199 }
1200
1201 buf[result_length] = 0;
1202
1203 *target_path = buf;
1204 return TRUE;
1205}
1206
1207static int
1208win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1209 BOOL traverse);
1210static int
1211win32_xstat_impl(const char *path, struct win32_stat *result,
1212 BOOL traverse)
1213{
Victor Stinner26de69d2011-06-17 15:15:38 +02001214 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001215 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001216 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001217 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001218 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001219 const char *dot;
1220
Brian Curtind25aef52011-06-13 15:16:04 -05001221 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001222 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1223 traverse reparse point. */
1224 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001225 }
1226
Brian Curtinf5e76d02010-11-24 13:14:05 +00001227 hFile = CreateFileA(
1228 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001229 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001230 0, /* share mode */
1231 NULL, /* security attributes */
1232 OPEN_EXISTING,
1233 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001234 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1235 Because of this, calls like GetFinalPathNameByHandle will return
1236 the symlink path agin and not the actual final path. */
1237 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1238 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001239 NULL);
1240
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001241 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001242 /* Either the target doesn't exist, or we don't have access to
1243 get a handle to it. If the former, we need to return an error.
1244 If the latter, we can use attributes_from_dir. */
1245 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001246 return -1;
1247 /* Could not get attributes on open file. Fall back to
1248 reading the directory. */
1249 if (!attributes_from_dir(path, &info, &reparse_tag))
1250 /* Very strange. This should not fail now */
1251 return -1;
1252 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1253 if (traverse) {
1254 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001255 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001256 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001257 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001258 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001259 } else {
1260 if (!GetFileInformationByHandle(hFile, &info)) {
1261 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001262 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001263 }
1264 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001265 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1266 return -1;
1267
1268 /* Close the outer open file handle now that we're about to
1269 reopen it with different flags. */
1270 if (!CloseHandle(hFile))
1271 return -1;
1272
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001273 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001274 /* In order to call GetFinalPathNameByHandle we need to open
1275 the file without the reparse handling flag set. */
1276 hFile2 = CreateFileA(
1277 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1278 NULL, OPEN_EXISTING,
1279 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1280 NULL);
1281 if (hFile2 == INVALID_HANDLE_VALUE)
1282 return -1;
1283
1284 if (!get_target_path(hFile2, &target_path))
1285 return -1;
1286
1287 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001288 free(target_path);
1289 return code;
1290 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001291 } else
1292 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001293 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001294 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001295
1296 /* Set S_IEXEC if it is an .exe, .bat, ... */
1297 dot = strrchr(path, '.');
1298 if (dot) {
1299 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1300 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1301 result->st_mode |= 0111;
1302 }
1303 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001304}
1305
1306static int
Brian Curtind25aef52011-06-13 15:16:04 -05001307win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1308 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001309{
1310 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001311 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001312 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001313 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001314 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001315 const wchar_t *dot;
1316
Brian Curtind25aef52011-06-13 15:16:04 -05001317 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001318 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1319 traverse reparse point. */
1320 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001321 }
1322
Brian Curtinf5e76d02010-11-24 13:14:05 +00001323 hFile = CreateFileW(
1324 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001325 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001326 0, /* share mode */
1327 NULL, /* security attributes */
1328 OPEN_EXISTING,
1329 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001330 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1331 Because of this, calls like GetFinalPathNameByHandle will return
1332 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001333 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001334 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001335 NULL);
1336
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001337 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001338 /* Either the target doesn't exist, or we don't have access to
1339 get a handle to it. If the former, we need to return an error.
1340 If the latter, we can use attributes_from_dir. */
1341 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001342 return -1;
1343 /* Could not get attributes on open file. Fall back to
1344 reading the directory. */
1345 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1346 /* Very strange. This should not fail now */
1347 return -1;
1348 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1349 if (traverse) {
1350 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001351 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001352 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001353 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001354 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001355 } else {
1356 if (!GetFileInformationByHandle(hFile, &info)) {
1357 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001358 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001359 }
1360 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001361 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1362 return -1;
1363
1364 /* Close the outer open file handle now that we're about to
1365 reopen it with different flags. */
1366 if (!CloseHandle(hFile))
1367 return -1;
1368
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001369 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001370 /* In order to call GetFinalPathNameByHandle we need to open
1371 the file without the reparse handling flag set. */
1372 hFile2 = CreateFileW(
1373 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1374 NULL, OPEN_EXISTING,
1375 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1376 NULL);
1377 if (hFile2 == INVALID_HANDLE_VALUE)
1378 return -1;
1379
1380 if (!get_target_path(hFile2, &target_path))
1381 return -1;
1382
1383 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001384 free(target_path);
1385 return code;
1386 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001387 } else
1388 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001389 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001390 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001391
1392 /* Set S_IEXEC if it is an .exe, .bat, ... */
1393 dot = wcsrchr(path, '.');
1394 if (dot) {
1395 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1396 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1397 result->st_mode |= 0111;
1398 }
1399 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001400}
1401
1402static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001403win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001404{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001405 /* Protocol violation: we explicitly clear errno, instead of
1406 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001407 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001408 errno = 0;
1409 return code;
1410}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001411
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001412static int
1413win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1414{
1415 /* Protocol violation: we explicitly clear errno, instead of
1416 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001417 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001418 errno = 0;
1419 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001420}
Brian Curtind25aef52011-06-13 15:16:04 -05001421/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001422
1423 In Posix, stat automatically traverses symlinks and returns the stat
1424 structure for the target. In Windows, the equivalent GetFileAttributes by
1425 default does not traverse symlinks and instead returns attributes for
1426 the symlink.
1427
1428 Therefore, win32_lstat will get the attributes traditionally, and
1429 win32_stat will first explicitly resolve the symlink target and then will
1430 call win32_lstat on that result.
1431
Ezio Melotti4969f702011-03-15 05:59:46 +02001432 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001433
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001434static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001435win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001436{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001437 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001438}
1439
Victor Stinner8c62be82010-05-06 00:08:46 +00001440static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001441win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001442{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001443 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001444}
1445
1446static int
1447win32_stat(const char* path, struct win32_stat *result)
1448{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001449 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001450}
1451
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001452static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001453win32_stat_w(const wchar_t* path, struct win32_stat *result)
1454{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001455 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001456}
1457
1458static int
1459win32_fstat(int file_number, struct win32_stat *result)
1460{
Victor Stinner8c62be82010-05-06 00:08:46 +00001461 BY_HANDLE_FILE_INFORMATION info;
1462 HANDLE h;
1463 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001464
Victor Stinner8c62be82010-05-06 00:08:46 +00001465 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001466
Victor Stinner8c62be82010-05-06 00:08:46 +00001467 /* Protocol violation: we explicitly clear errno, instead of
1468 setting it to a POSIX error. Callers should use GetLastError. */
1469 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001470
Victor Stinner8c62be82010-05-06 00:08:46 +00001471 if (h == INVALID_HANDLE_VALUE) {
1472 /* This is really a C library error (invalid file handle).
1473 We set the Win32 error to the closes one matching. */
1474 SetLastError(ERROR_INVALID_HANDLE);
1475 return -1;
1476 }
1477 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001478
Victor Stinner8c62be82010-05-06 00:08:46 +00001479 type = GetFileType(h);
1480 if (type == FILE_TYPE_UNKNOWN) {
1481 DWORD error = GetLastError();
1482 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001483 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001484 }
1485 /* else: valid but unknown file */
1486 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001487
Victor Stinner8c62be82010-05-06 00:08:46 +00001488 if (type != FILE_TYPE_DISK) {
1489 if (type == FILE_TYPE_CHAR)
1490 result->st_mode = _S_IFCHR;
1491 else if (type == FILE_TYPE_PIPE)
1492 result->st_mode = _S_IFIFO;
1493 return 0;
1494 }
1495
1496 if (!GetFileInformationByHandle(h, &info)) {
1497 return -1;
1498 }
1499
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001500 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001501 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001502 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1503 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001504}
1505
1506#endif /* MS_WINDOWS */
1507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001508PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001509"stat_result: Result from stat or lstat.\n\n\
1510This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001511 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001512or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1513\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001514Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1515or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001516\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001517See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001518
1519static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001520 {"st_mode", "protection bits"},
1521 {"st_ino", "inode"},
1522 {"st_dev", "device"},
1523 {"st_nlink", "number of hard links"},
1524 {"st_uid", "user ID of owner"},
1525 {"st_gid", "group ID of owner"},
1526 {"st_size", "total size, in bytes"},
1527 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1528 {NULL, "integer time of last access"},
1529 {NULL, "integer time of last modification"},
1530 {NULL, "integer time of last change"},
1531 {"st_atime", "time of last access"},
1532 {"st_mtime", "time of last modification"},
1533 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001534#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001535 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001536#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001537#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001538 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001539#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001540#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001542#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001543#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001545#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001546#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001548#endif
1549#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001550 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001551#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001553};
1554
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001555#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001556#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001557#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001558#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001559#endif
1560
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001561#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001562#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1563#else
1564#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1565#endif
1566
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001567#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001568#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1569#else
1570#define ST_RDEV_IDX ST_BLOCKS_IDX
1571#endif
1572
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001573#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1574#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1575#else
1576#define ST_FLAGS_IDX ST_RDEV_IDX
1577#endif
1578
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001579#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001580#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001581#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001582#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001583#endif
1584
1585#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1586#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1587#else
1588#define ST_BIRTHTIME_IDX ST_GEN_IDX
1589#endif
1590
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001591static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001592 "stat_result", /* name */
1593 stat_result__doc__, /* doc */
1594 stat_result_fields,
1595 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001596};
1597
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001598PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001599"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1600This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001601 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001602or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001603\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001604See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001605
1606static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001607 {"f_bsize", },
1608 {"f_frsize", },
1609 {"f_blocks", },
1610 {"f_bfree", },
1611 {"f_bavail", },
1612 {"f_files", },
1613 {"f_ffree", },
1614 {"f_favail", },
1615 {"f_flag", },
1616 {"f_namemax",},
1617 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001618};
1619
1620static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001621 "statvfs_result", /* name */
1622 statvfs_result__doc__, /* doc */
1623 statvfs_result_fields,
1624 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001625};
1626
Ross Lagerwall7807c352011-03-17 20:20:30 +02001627#if defined(HAVE_WAITID) && !defined(__APPLE__)
1628PyDoc_STRVAR(waitid_result__doc__,
1629"waitid_result: Result from waitid.\n\n\
1630This object may be accessed either as a tuple of\n\
1631 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1632or via the attributes si_pid, si_uid, and so on.\n\
1633\n\
1634See os.waitid for more information.");
1635
1636static PyStructSequence_Field waitid_result_fields[] = {
1637 {"si_pid", },
1638 {"si_uid", },
1639 {"si_signo", },
1640 {"si_status", },
1641 {"si_code", },
1642 {0}
1643};
1644
1645static PyStructSequence_Desc waitid_result_desc = {
1646 "waitid_result", /* name */
1647 waitid_result__doc__, /* doc */
1648 waitid_result_fields,
1649 5
1650};
1651static PyTypeObject WaitidResultType;
1652#endif
1653
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001654static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001655static PyTypeObject StatResultType;
1656static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001657#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001658static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001659#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001660static newfunc structseq_new;
1661
1662static PyObject *
1663statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1664{
Victor Stinner8c62be82010-05-06 00:08:46 +00001665 PyStructSequence *result;
1666 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001667
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 result = (PyStructSequence*)structseq_new(type, args, kwds);
1669 if (!result)
1670 return NULL;
1671 /* If we have been initialized from a tuple,
1672 st_?time might be set to None. Initialize it
1673 from the int slots. */
1674 for (i = 7; i <= 9; i++) {
1675 if (result->ob_item[i+3] == Py_None) {
1676 Py_DECREF(Py_None);
1677 Py_INCREF(result->ob_item[i]);
1678 result->ob_item[i+3] = result->ob_item[i];
1679 }
1680 }
1681 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001682}
1683
1684
1685
1686/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001687static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001688
1689PyDoc_STRVAR(stat_float_times__doc__,
1690"stat_float_times([newval]) -> oldval\n\n\
1691Determine whether os.[lf]stat represents time stamps as float objects.\n\
1692If newval is True, future calls to stat() return floats, if it is False,\n\
1693future calls return ints. \n\
1694If newval is omitted, return the current setting.\n");
1695
1696static PyObject*
1697stat_float_times(PyObject* self, PyObject *args)
1698{
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 int newval = -1;
1700 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1701 return NULL;
1702 if (newval == -1)
1703 /* Return old value */
1704 return PyBool_FromLong(_stat_float_times);
1705 _stat_float_times = newval;
1706 Py_INCREF(Py_None);
1707 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001708}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001709
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001710static void
1711fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1712{
Victor Stinner8c62be82010-05-06 00:08:46 +00001713 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001714#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001715 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001716#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001717 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001718#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001719 if (!ival)
1720 return;
1721 if (_stat_float_times) {
1722 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1723 } else {
1724 fval = ival;
1725 Py_INCREF(fval);
1726 }
1727 PyStructSequence_SET_ITEM(v, index, ival);
1728 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001729}
1730
Tim Peters5aa91602002-01-30 05:46:57 +00001731/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001732 (used by posix_stat() and posix_fstat()) */
1733static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001734_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001735{
Victor Stinner8c62be82010-05-06 00:08:46 +00001736 unsigned long ansec, mnsec, cnsec;
1737 PyObject *v = PyStructSequence_New(&StatResultType);
1738 if (v == NULL)
1739 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001740
Victor Stinner8c62be82010-05-06 00:08:46 +00001741 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001742#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001743 PyStructSequence_SET_ITEM(v, 1,
1744 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001745#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001746 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001747#endif
1748#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001749 PyStructSequence_SET_ITEM(v, 2,
1750 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001751#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001752 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001753#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1755 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1756 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001757#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 PyStructSequence_SET_ITEM(v, 6,
1759 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001760#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001761 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001762#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001763
Martin v. Löwis14694662006-02-03 12:54:16 +00001764#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001765 ansec = st->st_atim.tv_nsec;
1766 mnsec = st->st_mtim.tv_nsec;
1767 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001768#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001769 ansec = st->st_atimespec.tv_nsec;
1770 mnsec = st->st_mtimespec.tv_nsec;
1771 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001772#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 ansec = st->st_atime_nsec;
1774 mnsec = st->st_mtime_nsec;
1775 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001776#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001777 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001778#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 fill_time(v, 7, st->st_atime, ansec);
1780 fill_time(v, 8, st->st_mtime, mnsec);
1781 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001782
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001783#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1785 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001787#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001788 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1789 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001790#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001791#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001792 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1793 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001794#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001795#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001796 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1797 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001798#endif
1799#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001800 {
1801 PyObject *val;
1802 unsigned long bsec,bnsec;
1803 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001804#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001805 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001806#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001807 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001808#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001809 if (_stat_float_times) {
1810 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1811 } else {
1812 val = PyLong_FromLong((long)bsec);
1813 }
1814 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1815 val);
1816 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001817#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001818#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001819 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1820 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001821#endif
Fred Drake699f3522000-06-29 21:12:41 +00001822
Victor Stinner8c62be82010-05-06 00:08:46 +00001823 if (PyErr_Occurred()) {
1824 Py_DECREF(v);
1825 return NULL;
1826 }
Fred Drake699f3522000-06-29 21:12:41 +00001827
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001829}
1830
Barry Warsaw53699e91996-12-10 23:23:01 +00001831static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001832posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001833 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001834#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001836#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001838#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 char *wformat,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001840 int (*wstatfunc)(const wchar_t *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001841{
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 STRUCT_STAT st;
1843 PyObject *opath;
1844 char *path;
1845 int res;
1846 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001847
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001848#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001849 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 if (PyArg_ParseTuple(args, wformat, &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001851 wchar_t *wpath = PyUnicode_AsUnicode(po);
1852 if (wpath == NULL)
1853 return NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00001854
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 res = wstatfunc(wpath, &st);
1857 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001858
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 if (res != 0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001860 return win32_error_object("stat", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 return _pystat_fromstructstat(&st);
1862 }
1863 /* Drop the argument parsing error as narrow strings
1864 are also valid. */
1865 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001866#endif
1867
Victor Stinner8c62be82010-05-06 00:08:46 +00001868 if (!PyArg_ParseTuple(args, format,
1869 PyUnicode_FSConverter, &opath))
1870 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001871#ifdef MS_WINDOWS
1872 if (win32_warn_bytes_api()) {
1873 Py_DECREF(opath);
1874 return NULL;
1875 }
1876#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001877 path = PyBytes_AsString(opath);
1878 Py_BEGIN_ALLOW_THREADS
1879 res = (*statfunc)(path, &st);
1880 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001881
Victor Stinner8c62be82010-05-06 00:08:46 +00001882 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001883#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001884 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001885#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001886 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001887#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001888 }
1889 else
1890 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001891
Victor Stinner8c62be82010-05-06 00:08:46 +00001892 Py_DECREF(opath);
1893 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001894}
1895
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001896/* POSIX methods */
1897
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001898PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001899"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001900Use the real uid/gid to test for access to a path. Note that most\n\
1901operations will use the effective uid/gid, therefore this routine can\n\
1902be used in a suid/sgid environment to test if the invoking user has the\n\
1903specified access to the path. The mode argument can be F_OK to test\n\
1904existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001905
1906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001907posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001908{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001909 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001910 int mode;
1911
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001912#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02001914 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001915 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001916 wchar_t* wpath = PyUnicode_AsUnicode(po);
1917 if (wpath == NULL)
1918 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001920 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 Py_END_ALLOW_THREADS
1922 goto finish;
1923 }
1924 /* Drop the argument parsing error as narrow strings
1925 are also valid. */
1926 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001927 if (!PyArg_ParseTuple(args, "yi:access", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00001928 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001929 if (win32_warn_bytes_api())
1930 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 Py_BEGIN_ALLOW_THREADS
1932 attr = GetFileAttributesA(path);
1933 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001934finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 if (attr == 0xFFFFFFFF)
1936 /* File does not exist, or cannot read attributes */
1937 return PyBool_FromLong(0);
1938 /* Access is possible if either write access wasn't requested, or
1939 the file isn't read-only, or if it's a directory, as there are
1940 no read-only directories on Windows. */
1941 return PyBool_FromLong(!(mode & 2)
1942 || !(attr & FILE_ATTRIBUTE_READONLY)
1943 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001944#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001945 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 int res;
1947 if (!PyArg_ParseTuple(args, "O&i:access",
1948 PyUnicode_FSConverter, &opath, &mode))
1949 return NULL;
1950 path = PyBytes_AsString(opath);
1951 Py_BEGIN_ALLOW_THREADS
1952 res = access(path, mode);
1953 Py_END_ALLOW_THREADS
1954 Py_DECREF(opath);
1955 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001956#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001957}
1958
Guido van Rossumd371ff11999-01-25 16:12:23 +00001959#ifndef F_OK
1960#define F_OK 0
1961#endif
1962#ifndef R_OK
1963#define R_OK 4
1964#endif
1965#ifndef W_OK
1966#define W_OK 2
1967#endif
1968#ifndef X_OK
1969#define X_OK 1
1970#endif
1971
1972#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001973PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001974"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001975Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001976
1977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001978posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001979{
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 int id;
1981 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001982
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1984 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001985
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001986#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001987 /* file descriptor 0 only, the default input device (stdin) */
1988 if (id == 0) {
1989 ret = ttyname();
1990 }
1991 else {
1992 ret = NULL;
1993 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001994#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001995 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001996#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 if (ret == NULL)
1998 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001999 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002000}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002001#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002002
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002003#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002004PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002005"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002006Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002007
2008static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002009posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002010{
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 char *ret;
2012 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002013
Greg Wardb48bc172000-03-01 21:51:56 +00002014#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002015 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002016#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002018#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 if (ret == NULL)
2020 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002021 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002022}
2023#endif
2024
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002025PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002026"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002027Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002028
Barry Warsaw53699e91996-12-10 23:23:01 +00002029static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002030posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002031{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002032#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002034#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00002036#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002038#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002039 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002040#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002041}
2042
Fred Drake4d1e64b2002-04-15 19:40:07 +00002043#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002044PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002045"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00002046Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002048
2049static PyObject *
2050posix_fchdir(PyObject *self, PyObject *fdobj)
2051{
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002053}
2054#endif /* HAVE_FCHDIR */
2055
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002056
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002058"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002059Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002060
Barry Warsaw53699e91996-12-10 23:23:01 +00002061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002062posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002063{
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 PyObject *opath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002065 const char *path = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002066 int i;
2067 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002068#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002070 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00002071 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002072 wchar_t *wpath = PyUnicode_AsUnicode(po);
2073 if (wpath == NULL)
2074 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002076 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 if (attr != 0xFFFFFFFF) {
2078 if (i & _S_IWRITE)
2079 attr &= ~FILE_ATTRIBUTE_READONLY;
2080 else
2081 attr |= FILE_ATTRIBUTE_READONLY;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002082 res = SetFileAttributesW(wpath, attr);
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 }
2084 else
2085 res = 0;
2086 Py_END_ALLOW_THREADS
2087 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02002088 return win32_error_object("chmod", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 Py_INCREF(Py_None);
2090 return Py_None;
2091 }
2092 /* Drop the argument parsing error as narrow strings
2093 are also valid. */
2094 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002095
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002096 if (!PyArg_ParseTuple(args, "yi:chmod", &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002097 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002098 if (win32_warn_bytes_api())
2099 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 Py_BEGIN_ALLOW_THREADS
2101 attr = GetFileAttributesA(path);
2102 if (attr != 0xFFFFFFFF) {
2103 if (i & _S_IWRITE)
2104 attr &= ~FILE_ATTRIBUTE_READONLY;
2105 else
2106 attr |= FILE_ATTRIBUTE_READONLY;
2107 res = SetFileAttributesA(path, attr);
2108 }
2109 else
2110 res = 0;
2111 Py_END_ALLOW_THREADS
2112 if (!res) {
2113 win32_error("chmod", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002114 return NULL;
2115 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002116 Py_INCREF(Py_None);
2117 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002118#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002119 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2120 &opath, &i))
2121 return NULL;
2122 path = PyBytes_AsString(opath);
2123 Py_BEGIN_ALLOW_THREADS
2124 res = chmod(path, i);
2125 Py_END_ALLOW_THREADS
2126 if (res < 0)
2127 return posix_error_with_allocated_filename(opath);
2128 Py_DECREF(opath);
2129 Py_INCREF(Py_None);
2130 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002131#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002132}
2133
Christian Heimes4e30a842007-11-30 22:12:06 +00002134#ifdef HAVE_FCHMOD
2135PyDoc_STRVAR(posix_fchmod__doc__,
2136"fchmod(fd, mode)\n\n\
2137Change the access permissions of the file given by file\n\
2138descriptor fd.");
2139
2140static PyObject *
2141posix_fchmod(PyObject *self, PyObject *args)
2142{
Victor Stinner8c62be82010-05-06 00:08:46 +00002143 int fd, mode, res;
2144 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2145 return NULL;
2146 Py_BEGIN_ALLOW_THREADS
2147 res = fchmod(fd, mode);
2148 Py_END_ALLOW_THREADS
2149 if (res < 0)
2150 return posix_error();
2151 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002152}
2153#endif /* HAVE_FCHMOD */
2154
2155#ifdef HAVE_LCHMOD
2156PyDoc_STRVAR(posix_lchmod__doc__,
2157"lchmod(path, mode)\n\n\
2158Change the access permissions of a file. If path is a symlink, this\n\
2159affects the link itself rather than the target.");
2160
2161static PyObject *
2162posix_lchmod(PyObject *self, PyObject *args)
2163{
Victor Stinner8c62be82010-05-06 00:08:46 +00002164 PyObject *opath;
2165 char *path;
2166 int i;
2167 int res;
2168 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2169 &opath, &i))
2170 return NULL;
2171 path = PyBytes_AsString(opath);
2172 Py_BEGIN_ALLOW_THREADS
2173 res = lchmod(path, i);
2174 Py_END_ALLOW_THREADS
2175 if (res < 0)
2176 return posix_error_with_allocated_filename(opath);
2177 Py_DECREF(opath);
2178 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002179}
2180#endif /* HAVE_LCHMOD */
2181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002182
Thomas Wouterscf297e42007-02-23 15:07:44 +00002183#ifdef HAVE_CHFLAGS
2184PyDoc_STRVAR(posix_chflags__doc__,
2185"chflags(path, flags)\n\n\
2186Set file flags.");
2187
2188static PyObject *
2189posix_chflags(PyObject *self, PyObject *args)
2190{
Victor Stinner8c62be82010-05-06 00:08:46 +00002191 PyObject *opath;
2192 char *path;
2193 unsigned long flags;
2194 int res;
2195 if (!PyArg_ParseTuple(args, "O&k:chflags",
2196 PyUnicode_FSConverter, &opath, &flags))
2197 return NULL;
2198 path = PyBytes_AsString(opath);
2199 Py_BEGIN_ALLOW_THREADS
2200 res = chflags(path, flags);
2201 Py_END_ALLOW_THREADS
2202 if (res < 0)
2203 return posix_error_with_allocated_filename(opath);
2204 Py_DECREF(opath);
2205 Py_INCREF(Py_None);
2206 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002207}
2208#endif /* HAVE_CHFLAGS */
2209
2210#ifdef HAVE_LCHFLAGS
2211PyDoc_STRVAR(posix_lchflags__doc__,
2212"lchflags(path, flags)\n\n\
2213Set file flags.\n\
2214This function will not follow symbolic links.");
2215
2216static PyObject *
2217posix_lchflags(PyObject *self, PyObject *args)
2218{
Victor Stinner8c62be82010-05-06 00:08:46 +00002219 PyObject *opath;
2220 char *path;
2221 unsigned long flags;
2222 int res;
2223 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2224 PyUnicode_FSConverter, &opath, &flags))
2225 return NULL;
2226 path = PyBytes_AsString(opath);
2227 Py_BEGIN_ALLOW_THREADS
2228 res = lchflags(path, flags);
2229 Py_END_ALLOW_THREADS
2230 if (res < 0)
2231 return posix_error_with_allocated_filename(opath);
2232 Py_DECREF(opath);
2233 Py_INCREF(Py_None);
2234 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002235}
2236#endif /* HAVE_LCHFLAGS */
2237
Martin v. Löwis244edc82001-10-04 22:44:26 +00002238#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002239PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002240"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002241Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002242
2243static PyObject *
2244posix_chroot(PyObject *self, PyObject *args)
2245{
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002247}
2248#endif
2249
Guido van Rossum21142a01999-01-08 21:05:37 +00002250#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002251PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002252"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002253force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002254
2255static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002256posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002257{
Stefan Krah0e803b32010-11-26 16:16:47 +00002258 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002259}
2260#endif /* HAVE_FSYNC */
2261
Ross Lagerwall7807c352011-03-17 20:20:30 +02002262#ifdef HAVE_SYNC
2263PyDoc_STRVAR(posix_sync__doc__,
2264"sync()\n\n\
2265Force write of everything to disk.");
2266
2267static PyObject *
2268posix_sync(PyObject *self, PyObject *noargs)
2269{
2270 Py_BEGIN_ALLOW_THREADS
2271 sync();
2272 Py_END_ALLOW_THREADS
2273 Py_RETURN_NONE;
2274}
2275#endif
2276
Guido van Rossum21142a01999-01-08 21:05:37 +00002277#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002278
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002279#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002280extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2281#endif
2282
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002283PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002284"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002285force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002286 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002287
2288static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002289posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002290{
Stefan Krah0e803b32010-11-26 16:16:47 +00002291 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002292}
2293#endif /* HAVE_FDATASYNC */
2294
2295
Fredrik Lundh10723342000-07-10 16:38:09 +00002296#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002297PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002298"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002299Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002300
Barry Warsaw53699e91996-12-10 23:23:01 +00002301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002302posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002303{
Victor Stinner8c62be82010-05-06 00:08:46 +00002304 PyObject *opath;
2305 char *path;
2306 long uid, gid;
2307 int res;
2308 if (!PyArg_ParseTuple(args, "O&ll:chown",
2309 PyUnicode_FSConverter, &opath,
2310 &uid, &gid))
2311 return NULL;
2312 path = PyBytes_AsString(opath);
2313 Py_BEGIN_ALLOW_THREADS
2314 res = chown(path, (uid_t) uid, (gid_t) gid);
2315 Py_END_ALLOW_THREADS
2316 if (res < 0)
2317 return posix_error_with_allocated_filename(opath);
2318 Py_DECREF(opath);
2319 Py_INCREF(Py_None);
2320 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002321}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002322#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002323
Christian Heimes4e30a842007-11-30 22:12:06 +00002324#ifdef HAVE_FCHOWN
2325PyDoc_STRVAR(posix_fchown__doc__,
2326"fchown(fd, uid, gid)\n\n\
2327Change the owner and group id of the file given by file descriptor\n\
2328fd to the numeric uid and gid.");
2329
2330static PyObject *
2331posix_fchown(PyObject *self, PyObject *args)
2332{
Victor Stinner8c62be82010-05-06 00:08:46 +00002333 int fd;
2334 long uid, gid;
2335 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002336 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002337 return NULL;
2338 Py_BEGIN_ALLOW_THREADS
2339 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2340 Py_END_ALLOW_THREADS
2341 if (res < 0)
2342 return posix_error();
2343 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002344}
2345#endif /* HAVE_FCHOWN */
2346
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002347#ifdef HAVE_LCHOWN
2348PyDoc_STRVAR(posix_lchown__doc__,
2349"lchown(path, uid, gid)\n\n\
2350Change the owner and group id of path to the numeric uid and gid.\n\
2351This function will not follow symbolic links.");
2352
2353static PyObject *
2354posix_lchown(PyObject *self, PyObject *args)
2355{
Victor Stinner8c62be82010-05-06 00:08:46 +00002356 PyObject *opath;
2357 char *path;
2358 long uid, gid;
2359 int res;
2360 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2361 PyUnicode_FSConverter, &opath,
2362 &uid, &gid))
2363 return NULL;
2364 path = PyBytes_AsString(opath);
2365 Py_BEGIN_ALLOW_THREADS
2366 res = lchown(path, (uid_t) uid, (gid_t) gid);
2367 Py_END_ALLOW_THREADS
2368 if (res < 0)
2369 return posix_error_with_allocated_filename(opath);
2370 Py_DECREF(opath);
2371 Py_INCREF(Py_None);
2372 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002373}
2374#endif /* HAVE_LCHOWN */
2375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002376
Guido van Rossum36bc6801995-06-14 22:54:23 +00002377#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002378static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002379posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002380{
Victor Stinner8c62be82010-05-06 00:08:46 +00002381 char buf[1026];
2382 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002383
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002384#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002385 if (!use_bytes) {
2386 wchar_t wbuf[1026];
2387 wchar_t *wbuf2 = wbuf;
2388 PyObject *resobj;
2389 DWORD len;
2390 Py_BEGIN_ALLOW_THREADS
2391 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2392 /* If the buffer is large enough, len does not include the
2393 terminating \0. If the buffer is too small, len includes
2394 the space needed for the terminator. */
2395 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2396 wbuf2 = malloc(len * sizeof(wchar_t));
2397 if (wbuf2)
2398 len = GetCurrentDirectoryW(len, wbuf2);
2399 }
2400 Py_END_ALLOW_THREADS
2401 if (!wbuf2) {
2402 PyErr_NoMemory();
2403 return NULL;
2404 }
2405 if (!len) {
2406 if (wbuf2 != wbuf) free(wbuf2);
2407 return win32_error("getcwdu", NULL);
2408 }
2409 resobj = PyUnicode_FromWideChar(wbuf2, len);
2410 if (wbuf2 != wbuf) free(wbuf2);
2411 return resobj;
2412 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002413#endif
2414
Victor Stinner8c62be82010-05-06 00:08:46 +00002415 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002416#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002417 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002418#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002419 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002420#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002421 Py_END_ALLOW_THREADS
2422 if (res == NULL)
2423 return posix_error();
2424 if (use_bytes)
2425 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002426 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002427}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002428
2429PyDoc_STRVAR(posix_getcwd__doc__,
2430"getcwd() -> path\n\n\
2431Return a unicode string representing the current working directory.");
2432
2433static PyObject *
2434posix_getcwd_unicode(PyObject *self)
2435{
2436 return posix_getcwd(0);
2437}
2438
2439PyDoc_STRVAR(posix_getcwdb__doc__,
2440"getcwdb() -> path\n\n\
2441Return a bytes string representing the current working directory.");
2442
2443static PyObject *
2444posix_getcwd_bytes(PyObject *self)
2445{
2446 return posix_getcwd(1);
2447}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002448#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002449
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002450
Guido van Rossumb6775db1994-08-01 11:34:53 +00002451#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002452PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002453"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002454Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002455
Barry Warsaw53699e91996-12-10 23:23:01 +00002456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002457posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002458{
Victor Stinner8c62be82010-05-06 00:08:46 +00002459 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002460}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002461#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002462
Brian Curtin1b9df392010-11-24 20:24:31 +00002463#ifdef MS_WINDOWS
2464PyDoc_STRVAR(win32_link__doc__,
2465"link(src, dst)\n\n\
2466Create a hard link to a file.");
2467
2468static PyObject *
2469win32_link(PyObject *self, PyObject *args)
2470{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002471 PyObject *src, *dst;
2472 BOOL ok;
Brian Curtin1b9df392010-11-24 20:24:31 +00002473
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002474 if (PyArg_ParseTuple(args, "UU:link", &src, &dst))
Victor Stinnereb5657a2011-09-30 01:44:27 +02002475 {
2476 wchar_t *wsrc, *wdst;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002477
2478 wsrc = PyUnicode_AsUnicode(src);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002479 if (wsrc == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002480 goto error;
2481 wdst = PyUnicode_AsUnicode(dst);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002482 if (wdst == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002483 goto error;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002484
Brian Curtinfc889c42010-11-28 23:59:46 +00002485 Py_BEGIN_ALLOW_THREADS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002486 ok = CreateHardLinkW(wdst, wsrc, NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002487 Py_END_ALLOW_THREADS
2488
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002489 if (!ok)
Brian Curtinfc889c42010-11-28 23:59:46 +00002490 return win32_error("link", NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002491 Py_RETURN_NONE;
2492 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002493 else {
2494 PyErr_Clear();
2495 if (!PyArg_ParseTuple(args, "O&O&:link",
2496 PyUnicode_FSConverter, &src,
2497 PyUnicode_FSConverter, &dst))
2498 return NULL;
Brian Curtinfc889c42010-11-28 23:59:46 +00002499
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002500 if (win32_warn_bytes_api())
2501 goto error;
Brian Curtinfc889c42010-11-28 23:59:46 +00002502
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002503 Py_BEGIN_ALLOW_THREADS
2504 ok = CreateHardLinkA(PyBytes_AS_STRING(dst),
2505 PyBytes_AS_STRING(src),
2506 NULL);
2507 Py_END_ALLOW_THREADS
2508
2509 Py_XDECREF(src);
2510 Py_XDECREF(dst);
2511
2512 if (!ok)
2513 return win32_error("link", NULL);
2514 Py_RETURN_NONE;
2515
2516 error:
2517 Py_XDECREF(src);
2518 Py_XDECREF(dst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002519 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002520 }
Brian Curtin1b9df392010-11-24 20:24:31 +00002521}
2522#endif /* MS_WINDOWS */
2523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002525PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002526"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002527Return a list containing the names of the entries in the directory.\n\
2528\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002529 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002530\n\
2531The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002532entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002533
Barry Warsaw53699e91996-12-10 23:23:01 +00002534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002535posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002536{
Victor Stinner8c62be82010-05-06 00:08:46 +00002537 /* XXX Should redo this putting the (now four) versions of opendir
2538 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002539#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002540
Victor Stinner8c62be82010-05-06 00:08:46 +00002541 PyObject *d, *v;
2542 HANDLE hFindFile;
2543 BOOL result;
2544 WIN32_FIND_DATA FileData;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002545 const char *path;
2546 Py_ssize_t pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002547 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2548 char *bufptr = namebuf;
2549 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002550
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002551 PyObject *po = NULL;
2552 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002553 WIN32_FIND_DATAW wFileData;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002554 wchar_t *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002555
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002556 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002557 po_wchars = L".";
2558 len = 1;
2559 } else {
Victor Stinnerbeac78b2011-10-11 21:55:01 +02002560 po_wchars = PyUnicode_AsUnicodeAndSize(po, &len);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002561 if (po_wchars == NULL)
2562 return NULL;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002563 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002564 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002565 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2566 if (!wnamebuf) {
2567 PyErr_NoMemory();
2568 return NULL;
2569 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002570 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002572 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00002573 if (wch != L'/' && wch != L'\\' && wch != L':')
2574 wnamebuf[len++] = L'\\';
2575 wcscpy(wnamebuf + len, L"*.*");
2576 }
2577 if ((d = PyList_New(0)) == NULL) {
2578 free(wnamebuf);
2579 return NULL;
2580 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002581 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002582 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002583 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002584 if (hFindFile == INVALID_HANDLE_VALUE) {
2585 int error = GetLastError();
2586 if (error == ERROR_FILE_NOT_FOUND) {
2587 free(wnamebuf);
2588 return d;
2589 }
2590 Py_DECREF(d);
2591 win32_error_unicode("FindFirstFileW", wnamebuf);
2592 free(wnamebuf);
2593 return NULL;
2594 }
2595 do {
2596 /* Skip over . and .. */
2597 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2598 wcscmp(wFileData.cFileName, L"..") != 0) {
2599 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2600 if (v == NULL) {
2601 Py_DECREF(d);
2602 d = NULL;
2603 break;
2604 }
2605 if (PyList_Append(d, v) != 0) {
2606 Py_DECREF(v);
2607 Py_DECREF(d);
2608 d = NULL;
2609 break;
2610 }
2611 Py_DECREF(v);
2612 }
2613 Py_BEGIN_ALLOW_THREADS
2614 result = FindNextFileW(hFindFile, &wFileData);
2615 Py_END_ALLOW_THREADS
2616 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2617 it got to the end of the directory. */
2618 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2619 Py_DECREF(d);
2620 win32_error_unicode("FindNextFileW", wnamebuf);
2621 FindClose(hFindFile);
2622 free(wnamebuf);
2623 return NULL;
2624 }
2625 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002626
Victor Stinner8c62be82010-05-06 00:08:46 +00002627 if (FindClose(hFindFile) == FALSE) {
2628 Py_DECREF(d);
2629 win32_error_unicode("FindClose", wnamebuf);
2630 free(wnamebuf);
2631 return NULL;
2632 }
2633 free(wnamebuf);
2634 return d;
2635 }
2636 /* Drop the argument parsing error as narrow strings
2637 are also valid. */
2638 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002639
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002640 if (!PyArg_ParseTuple(args, "y#:listdir", &path, &pathlen))
Victor Stinner8c62be82010-05-06 00:08:46 +00002641 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002642 if (win32_warn_bytes_api())
2643 return NULL;
2644 if (pathlen+1 > MAX_PATH) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002645 PyErr_SetString(PyExc_ValueError, "path too long");
Victor Stinner8c62be82010-05-06 00:08:46 +00002646 return NULL;
2647 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002648 strcpy(namebuf, path);
2649 len = pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002650 if (len > 0) {
2651 char ch = namebuf[len-1];
2652 if (ch != SEP && ch != ALTSEP && ch != ':')
2653 namebuf[len++] = '/';
2654 strcpy(namebuf + len, "*.*");
2655 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002656
Victor Stinner8c62be82010-05-06 00:08:46 +00002657 if ((d = PyList_New(0)) == NULL)
2658 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002659
Antoine Pitroub73caab2010-08-09 23:39:31 +00002660 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002661 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002662 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002663 if (hFindFile == INVALID_HANDLE_VALUE) {
2664 int error = GetLastError();
2665 if (error == ERROR_FILE_NOT_FOUND)
2666 return d;
2667 Py_DECREF(d);
2668 return win32_error("FindFirstFile", namebuf);
2669 }
2670 do {
2671 /* Skip over . and .. */
2672 if (strcmp(FileData.cFileName, ".") != 0 &&
2673 strcmp(FileData.cFileName, "..") != 0) {
2674 v = PyBytes_FromString(FileData.cFileName);
2675 if (v == NULL) {
2676 Py_DECREF(d);
2677 d = NULL;
2678 break;
2679 }
2680 if (PyList_Append(d, v) != 0) {
2681 Py_DECREF(v);
2682 Py_DECREF(d);
2683 d = NULL;
2684 break;
2685 }
2686 Py_DECREF(v);
2687 }
2688 Py_BEGIN_ALLOW_THREADS
2689 result = FindNextFile(hFindFile, &FileData);
2690 Py_END_ALLOW_THREADS
2691 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2692 it got to the end of the directory. */
2693 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2694 Py_DECREF(d);
2695 win32_error("FindNextFile", namebuf);
2696 FindClose(hFindFile);
2697 return NULL;
2698 }
2699 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002700
Victor Stinner8c62be82010-05-06 00:08:46 +00002701 if (FindClose(hFindFile) == FALSE) {
2702 Py_DECREF(d);
2703 return win32_error("FindClose", namebuf);
2704 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002705
Victor Stinner8c62be82010-05-06 00:08:46 +00002706 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002707
Tim Peters0bb44a42000-09-15 07:44:49 +00002708#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002709
2710#ifndef MAX_PATH
2711#define MAX_PATH CCHMAXPATH
2712#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002713 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002714 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002715 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002716 PyObject *d, *v;
2717 char namebuf[MAX_PATH+5];
2718 HDIR hdir = 1;
2719 ULONG srchcnt = 1;
2720 FILEFINDBUF3 ep;
2721 APIRET rc;
2722
Victor Stinner8c62be82010-05-06 00:08:46 +00002723 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002724 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002725 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002726 name = PyBytes_AsString(oname);
2727 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002728 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002729 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002730 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002731 return NULL;
2732 }
2733 strcpy(namebuf, name);
2734 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002735 if (*pt == ALTSEP)
2736 *pt = SEP;
2737 if (namebuf[len-1] != SEP)
2738 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002739 strcpy(namebuf + len, "*.*");
2740
Neal Norwitz6c913782007-10-14 03:23:09 +00002741 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002742 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002743 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002744 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002745
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002746 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2747 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002748 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002749 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2750 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2751 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002752
2753 if (rc != NO_ERROR) {
2754 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002755 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002756 }
2757
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002758 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002759 do {
2760 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002761 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002762 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002763
2764 strcpy(namebuf, ep.achName);
2765
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002766 /* Leave Case of Name Alone -- In Native Form */
2767 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002768
Christian Heimes72b710a2008-05-26 13:28:38 +00002769 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002770 if (v == NULL) {
2771 Py_DECREF(d);
2772 d = NULL;
2773 break;
2774 }
2775 if (PyList_Append(d, v) != 0) {
2776 Py_DECREF(v);
2777 Py_DECREF(d);
2778 d = NULL;
2779 break;
2780 }
2781 Py_DECREF(v);
2782 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2783 }
2784
Victor Stinnerdcb24032010-04-22 12:08:36 +00002785 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002786 return d;
2787#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002788 PyObject *oname;
2789 char *name;
2790 PyObject *d, *v;
2791 DIR *dirp;
2792 struct dirent *ep;
2793 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002794
Victor Stinner8c62be82010-05-06 00:08:46 +00002795 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002796 /* v is never read, so it does not need to be initialized yet. */
2797 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002798 arg_is_unicode = 0;
2799 PyErr_Clear();
2800 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002801 oname = NULL;
2802 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002803 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002804 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002805 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002806 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002807 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002808 Py_BEGIN_ALLOW_THREADS
2809 dirp = opendir(name);
2810 Py_END_ALLOW_THREADS
2811 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002812 return posix_error_with_allocated_filename(oname);
2813 }
2814 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002815 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002816 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002817 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 Py_DECREF(oname);
2819 return NULL;
2820 }
2821 for (;;) {
2822 errno = 0;
2823 Py_BEGIN_ALLOW_THREADS
2824 ep = readdir(dirp);
2825 Py_END_ALLOW_THREADS
2826 if (ep == NULL) {
2827 if (errno == 0) {
2828 break;
2829 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002830 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002831 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002832 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002833 Py_DECREF(d);
2834 return posix_error_with_allocated_filename(oname);
2835 }
2836 }
2837 if (ep->d_name[0] == '.' &&
2838 (NAMLEN(ep) == 1 ||
2839 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2840 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002841 if (arg_is_unicode)
2842 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2843 else
2844 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002845 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002846 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002847 break;
2848 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 if (PyList_Append(d, v) != 0) {
2850 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002851 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002852 break;
2853 }
2854 Py_DECREF(v);
2855 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002856 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002857 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002858 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002859 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002860
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002862
Tim Peters0bb44a42000-09-15 07:44:49 +00002863#endif /* which OS */
2864} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002865
Antoine Pitrou8250e232011-02-25 23:41:16 +00002866#ifdef HAVE_FDOPENDIR
2867PyDoc_STRVAR(posix_fdlistdir__doc__,
2868"fdlistdir(fd) -> list_of_strings\n\n\
2869Like listdir(), but uses a file descriptor instead.\n\
2870After succesful execution of this function, fd will be closed.");
2871
2872static PyObject *
2873posix_fdlistdir(PyObject *self, PyObject *args)
2874{
2875 PyObject *d, *v;
2876 DIR *dirp;
2877 struct dirent *ep;
2878 int fd;
2879
2880 errno = 0;
2881 if (!PyArg_ParseTuple(args, "i:fdlistdir", &fd))
2882 return NULL;
2883 Py_BEGIN_ALLOW_THREADS
2884 dirp = fdopendir(fd);
2885 Py_END_ALLOW_THREADS
2886 if (dirp == NULL) {
2887 close(fd);
2888 return posix_error();
2889 }
2890 if ((d = PyList_New(0)) == NULL) {
2891 Py_BEGIN_ALLOW_THREADS
2892 closedir(dirp);
2893 Py_END_ALLOW_THREADS
2894 return NULL;
2895 }
2896 for (;;) {
2897 errno = 0;
2898 Py_BEGIN_ALLOW_THREADS
2899 ep = readdir(dirp);
2900 Py_END_ALLOW_THREADS
2901 if (ep == NULL) {
2902 if (errno == 0) {
2903 break;
2904 } else {
2905 Py_BEGIN_ALLOW_THREADS
2906 closedir(dirp);
2907 Py_END_ALLOW_THREADS
2908 Py_DECREF(d);
2909 return posix_error();
2910 }
2911 }
2912 if (ep->d_name[0] == '.' &&
2913 (NAMLEN(ep) == 1 ||
2914 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2915 continue;
2916 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2917 if (v == NULL) {
2918 Py_CLEAR(d);
2919 break;
2920 }
2921 if (PyList_Append(d, v) != 0) {
2922 Py_DECREF(v);
2923 Py_CLEAR(d);
2924 break;
2925 }
2926 Py_DECREF(v);
2927 }
2928 Py_BEGIN_ALLOW_THREADS
2929 closedir(dirp);
2930 Py_END_ALLOW_THREADS
2931
2932 return d;
2933}
2934#endif
2935
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002936#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002937/* A helper function for abspath on win32 */
2938static PyObject *
2939posix__getfullpathname(PyObject *self, PyObject *args)
2940{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002941 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 char outbuf[MAX_PATH*2];
2943 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002944 PyObject *po;
2945
2946 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
2947 {
2948 wchar_t *wpath;
2949 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2950 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00002951 DWORD result;
2952 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002953
2954 wpath = PyUnicode_AsUnicode(po);
2955 if (wpath == NULL)
2956 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002957 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02002958 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00002959 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02002960 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002961 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00002962 if (!woutbufp)
2963 return PyErr_NoMemory();
2964 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2965 }
2966 if (result)
2967 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2968 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02002969 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 if (woutbufp != woutbuf)
2971 free(woutbufp);
2972 return v;
2973 }
2974 /* Drop the argument parsing error as narrow strings
2975 are also valid. */
2976 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02002977
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002978 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
2979 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00002980 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002981 if (win32_warn_bytes_api())
2982 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02002983 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00002984 outbuf, &temp)) {
2985 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002986 return NULL;
2987 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002988 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2989 return PyUnicode_Decode(outbuf, strlen(outbuf),
2990 Py_FileSystemDefaultEncoding, NULL);
2991 }
2992 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002993} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002994
Brian Curtind25aef52011-06-13 15:16:04 -05002995
Brian Curtinf5e76d02010-11-24 13:14:05 +00002996
Brian Curtind40e6f72010-07-08 21:39:08 +00002997/* A helper function for samepath on windows */
2998static PyObject *
2999posix__getfinalpathname(PyObject *self, PyObject *args)
3000{
3001 HANDLE hFile;
3002 int buf_size;
3003 wchar_t *target_path;
3004 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003005 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003006 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003007
Victor Stinnereb5657a2011-09-30 01:44:27 +02003008 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003009 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003010 path = PyUnicode_AsUnicode(po);
3011 if (path == NULL)
3012 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003013
3014 if(!check_GetFinalPathNameByHandle()) {
3015 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3016 NotImplementedError. */
3017 return PyErr_Format(PyExc_NotImplementedError,
3018 "GetFinalPathNameByHandle not available on this platform");
3019 }
3020
3021 hFile = CreateFileW(
3022 path,
3023 0, /* desired access */
3024 0, /* share mode */
3025 NULL, /* security attributes */
3026 OPEN_EXISTING,
3027 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3028 FILE_FLAG_BACKUP_SEMANTICS,
3029 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003030
Victor Stinnereb5657a2011-09-30 01:44:27 +02003031 if(hFile == INVALID_HANDLE_VALUE)
3032 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003033
3034 /* We have a good handle to the target, use it to determine the
3035 target path name. */
3036 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3037
3038 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003039 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003040
3041 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3042 if(!target_path)
3043 return PyErr_NoMemory();
3044
3045 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3046 buf_size, VOLUME_NAME_DOS);
3047 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003048 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003049
3050 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003051 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003052
3053 target_path[result_length] = 0;
3054 result = PyUnicode_FromUnicode(target_path, result_length);
3055 free(target_path);
3056 return result;
3057
3058} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003059
3060static PyObject *
3061posix__getfileinformation(PyObject *self, PyObject *args)
3062{
3063 HANDLE hFile;
3064 BY_HANDLE_FILE_INFORMATION info;
3065 int fd;
3066
3067 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3068 return NULL;
3069
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003070 if (!_PyVerify_fd(fd))
3071 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003072
3073 hFile = (HANDLE)_get_osfhandle(fd);
3074 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003075 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003076
3077 if (!GetFileInformationByHandle(hFile, &info))
3078 return win32_error("_getfileinformation", NULL);
3079
3080 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3081 info.nFileIndexHigh,
3082 info.nFileIndexLow);
3083}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003084
Brian Curtin95d028f2011-06-09 09:10:38 -05003085PyDoc_STRVAR(posix__isdir__doc__,
3086"Return true if the pathname refers to an existing directory.");
3087
Brian Curtin9c669cc2011-06-08 18:17:18 -05003088static PyObject *
3089posix__isdir(PyObject *self, PyObject *args)
3090{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003091 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003092 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003093 DWORD attributes;
3094
3095 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003096 wchar_t *wpath = PyUnicode_AsUnicode(po);
3097 if (wpath == NULL)
3098 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003099
3100 attributes = GetFileAttributesW(wpath);
3101 if (attributes == INVALID_FILE_ATTRIBUTES)
3102 Py_RETURN_FALSE;
3103 goto check;
3104 }
3105 /* Drop the argument parsing error as narrow strings
3106 are also valid. */
3107 PyErr_Clear();
3108
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003109 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003110 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003111 if (win32_warn_bytes_api())
3112 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003113 attributes = GetFileAttributesA(path);
3114 if (attributes == INVALID_FILE_ATTRIBUTES)
3115 Py_RETURN_FALSE;
3116
3117check:
3118 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3119 Py_RETURN_TRUE;
3120 else
3121 Py_RETURN_FALSE;
3122}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003123#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003125PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003126"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003127Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003128
Barry Warsaw53699e91996-12-10 23:23:01 +00003129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003130posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003131{
Victor Stinner8c62be82010-05-06 00:08:46 +00003132 int res;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003133 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003134 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003135
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003136#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003137 PyObject *po;
3138 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode))
3139 {
3140 wchar_t *wpath = PyUnicode_AsUnicode(po);
3141 if (wpath == NULL)
3142 return NULL;
3143
Victor Stinner8c62be82010-05-06 00:08:46 +00003144 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003145 res = CreateDirectoryW(wpath, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003146 Py_END_ALLOW_THREADS
3147 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003148 return win32_error_object("mkdir", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003149 Py_INCREF(Py_None);
3150 return Py_None;
3151 }
3152 /* Drop the argument parsing error as narrow strings
3153 are also valid. */
3154 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003155 if (!PyArg_ParseTuple(args, "y|i:mkdir", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00003156 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003157 if (win32_warn_bytes_api())
3158 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003160 res = CreateDirectoryA(path, NULL);
3161 Py_END_ALLOW_THREADS
3162 if (!res) {
3163 win32_error("mkdir", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003164 return NULL;
3165 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 Py_INCREF(Py_None);
3167 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003168#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003169 PyObject *opath;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003170
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3172 PyUnicode_FSConverter, &opath, &mode))
3173 return NULL;
3174 path = PyBytes_AsString(opath);
3175 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00003176#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00003177 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003178#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003179 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003180#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003181 Py_END_ALLOW_THREADS
3182 if (res < 0)
3183 return posix_error_with_allocated_filename(opath);
3184 Py_DECREF(opath);
3185 Py_INCREF(Py_None);
3186 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003187#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003188}
3189
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003190
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003191/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3192#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003193#include <sys/resource.h>
3194#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003195
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003196
3197#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003198PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003199"nice(inc) -> new_priority\n\n\
3200Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003201
Barry Warsaw53699e91996-12-10 23:23:01 +00003202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003203posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003204{
Victor Stinner8c62be82010-05-06 00:08:46 +00003205 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003206
Victor Stinner8c62be82010-05-06 00:08:46 +00003207 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3208 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003209
Victor Stinner8c62be82010-05-06 00:08:46 +00003210 /* There are two flavours of 'nice': one that returns the new
3211 priority (as required by almost all standards out there) and the
3212 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3213 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003214
Victor Stinner8c62be82010-05-06 00:08:46 +00003215 If we are of the nice family that returns the new priority, we
3216 need to clear errno before the call, and check if errno is filled
3217 before calling posix_error() on a returnvalue of -1, because the
3218 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003219
Victor Stinner8c62be82010-05-06 00:08:46 +00003220 errno = 0;
3221 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003222#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 if (value == 0)
3224 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003225#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 if (value == -1 && errno != 0)
3227 /* either nice() or getpriority() returned an error */
3228 return posix_error();
3229 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003230}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003231#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003232
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003233
3234#ifdef HAVE_GETPRIORITY
3235PyDoc_STRVAR(posix_getpriority__doc__,
3236"getpriority(which, who) -> current_priority\n\n\
3237Get program scheduling priority.");
3238
3239static PyObject *
3240posix_getpriority(PyObject *self, PyObject *args)
3241{
3242 int which, who, retval;
3243
3244 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3245 return NULL;
3246 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003247 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003248 if (errno != 0)
3249 return posix_error();
3250 return PyLong_FromLong((long)retval);
3251}
3252#endif /* HAVE_GETPRIORITY */
3253
3254
3255#ifdef HAVE_SETPRIORITY
3256PyDoc_STRVAR(posix_setpriority__doc__,
3257"setpriority(which, who, prio) -> None\n\n\
3258Set program scheduling priority.");
3259
3260static PyObject *
3261posix_setpriority(PyObject *self, PyObject *args)
3262{
3263 int which, who, prio, retval;
3264
3265 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3266 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003267 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003268 if (retval == -1)
3269 return posix_error();
3270 Py_RETURN_NONE;
3271}
3272#endif /* HAVE_SETPRIORITY */
3273
3274
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003275PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003276"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003277Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003278
Barry Warsaw53699e91996-12-10 23:23:01 +00003279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003280posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003281{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003282#ifdef MS_WINDOWS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003283 PyObject *src, *dst;
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 BOOL result;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003285 if (PyArg_ParseTuple(args, "UU:rename", &src, &dst))
3286 {
3287 wchar_t *wsrc, *wdst;
3288
3289 wsrc = PyUnicode_AsUnicode(src);
3290 if (wsrc == NULL)
3291 return NULL;
3292 wdst = PyUnicode_AsUnicode(dst);
3293 if (wdst == NULL)
3294 return NULL;
3295 Py_BEGIN_ALLOW_THREADS
3296 result = MoveFileW(wsrc, wdst);
3297 Py_END_ALLOW_THREADS
3298 if (!result)
3299 return win32_error("rename", NULL);
3300 Py_INCREF(Py_None);
3301 return Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003302 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003303 else {
3304 PyErr_Clear();
3305 if (!PyArg_ParseTuple(args, "O&O&:rename",
3306 PyUnicode_FSConverter, &src,
3307 PyUnicode_FSConverter, &dst))
3308 return NULL;
3309
3310 if (win32_warn_bytes_api())
3311 goto error;
3312
3313 Py_BEGIN_ALLOW_THREADS
3314 result = MoveFileA(PyBytes_AS_STRING(src),
3315 PyBytes_AS_STRING(dst));
3316 Py_END_ALLOW_THREADS
3317
3318 Py_XDECREF(src);
3319 Py_XDECREF(dst);
3320
3321 if (!result)
3322 return win32_error("rename", NULL);
3323 Py_INCREF(Py_None);
3324 return Py_None;
3325
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003326error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003327 Py_XDECREF(src);
3328 Py_XDECREF(dst);
Victor Stinner8c62be82010-05-06 00:08:46 +00003329 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003330 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003331#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003333#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003334}
3335
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003336
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003337PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003338"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003339Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003340
Barry Warsaw53699e91996-12-10 23:23:01 +00003341static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003342posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003343{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003344#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003345 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003346#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003347 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003348#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003349}
3350
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003351
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003352PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003353"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003354Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003355
Barry Warsaw53699e91996-12-10 23:23:01 +00003356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003357posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003358{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003359#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00003360 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003361#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003363#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003364}
3365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003366
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003367#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003368PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003369"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003370Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003371
Barry Warsaw53699e91996-12-10 23:23:01 +00003372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003373posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003374{
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003376#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003377 wchar_t *command;
3378 if (!PyArg_ParseTuple(args, "u:system", &command))
3379 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003380
Victor Stinner8c62be82010-05-06 00:08:46 +00003381 Py_BEGIN_ALLOW_THREADS
3382 sts = _wsystem(command);
3383 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003384#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003385 PyObject *command_obj;
3386 char *command;
3387 if (!PyArg_ParseTuple(args, "O&:system",
3388 PyUnicode_FSConverter, &command_obj))
3389 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003390
Victor Stinner8c62be82010-05-06 00:08:46 +00003391 command = PyBytes_AsString(command_obj);
3392 Py_BEGIN_ALLOW_THREADS
3393 sts = system(command);
3394 Py_END_ALLOW_THREADS
3395 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003396#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003397 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003398}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003399#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003400
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003401
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003402PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003403"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003404Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003405
Barry Warsaw53699e91996-12-10 23:23:01 +00003406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003407posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003408{
Victor Stinner8c62be82010-05-06 00:08:46 +00003409 int i;
3410 if (!PyArg_ParseTuple(args, "i:umask", &i))
3411 return NULL;
3412 i = (int)umask(i);
3413 if (i < 0)
3414 return posix_error();
3415 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003416}
3417
Brian Curtind40e6f72010-07-08 21:39:08 +00003418#ifdef MS_WINDOWS
3419
3420/* override the default DeleteFileW behavior so that directory
3421symlinks can be removed with this function, the same as with
3422Unix symlinks */
3423BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3424{
3425 WIN32_FILE_ATTRIBUTE_DATA info;
3426 WIN32_FIND_DATAW find_data;
3427 HANDLE find_data_handle;
3428 int is_directory = 0;
3429 int is_link = 0;
3430
3431 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3432 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003433
Brian Curtind40e6f72010-07-08 21:39:08 +00003434 /* Get WIN32_FIND_DATA structure for the path to determine if
3435 it is a symlink */
3436 if(is_directory &&
3437 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3438 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3439
3440 if(find_data_handle != INVALID_HANDLE_VALUE) {
3441 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3442 FindClose(find_data_handle);
3443 }
3444 }
3445 }
3446
3447 if (is_directory && is_link)
3448 return RemoveDirectoryW(lpFileName);
3449
3450 return DeleteFileW(lpFileName);
3451}
3452#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003453
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003454PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003455"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003456Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003457
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003458PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003459"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003460Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003461
Barry Warsaw53699e91996-12-10 23:23:01 +00003462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003463posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003464{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003465#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003466 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3467 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003468#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003469 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003470#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003471}
3472
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003473
Guido van Rossumb6775db1994-08-01 11:34:53 +00003474#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003475PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003476"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003477Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003478
Barry Warsaw53699e91996-12-10 23:23:01 +00003479static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003480posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003481{
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 struct utsname u;
3483 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003484
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 Py_BEGIN_ALLOW_THREADS
3486 res = uname(&u);
3487 Py_END_ALLOW_THREADS
3488 if (res < 0)
3489 return posix_error();
3490 return Py_BuildValue("(sssss)",
3491 u.sysname,
3492 u.nodename,
3493 u.release,
3494 u.version,
3495 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003496}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003497#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003498
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003499
3500/*
3501 * Classic POSIX utime functions supported microseconds (1m/sec).
3502 * Newer POSIX functions support nanoseconds (1 billion per sec).
3503 * posixmodule now uses the new functions where possible.
3504 * This improves accuracy in many situations, for example shutil.copy2().
3505 *
3506 * The implementation isn't currently sophisticated enough to handle
3507 * a platform where HAVE_UTIMENSAT is true but HAVE_FUTIMENS is false.
3508 * Specifically, posix_futimes() would break.
3509 *
3510 * Supporting such a platform wouldn't be impossible; you'd need two
3511 * extract_time() functions, or make its precision a parameter.
3512 * Since such a platform seems unlikely we haven't bothered.
3513 */
3514#if defined(HAVE_UTIMENSAT)
3515#define EXTRACT_TIME_PRECISION (1e9)
3516#if !defined(HAVE_FUTIMENS)
3517#error You HAVE_UTIMENSAT but not HAVE_FUTIMENS... please see accompanying comment.
3518#endif
3519#else
3520#define EXTRACT_TIME_PRECISION (1e6)
3521#endif
3522
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003523static int
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003524extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003525{
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003526 time_t intval;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 if (PyFloat_Check(t)) {
3528 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003529 PyObject *intobj = PyNumber_Long(t);
Victor Stinner8c62be82010-05-06 00:08:46 +00003530 if (!intobj)
3531 return -1;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003532#if SIZEOF_TIME_T > SIZEOF_LONG
3533 intval = PyLong_AsUnsignedLongLongMask(intobj);
3534#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 intval = PyLong_AsLong(intobj);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003536#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003537 Py_DECREF(intobj);
3538 if (intval == -1 && PyErr_Occurred())
3539 return -1;
3540 *sec = intval;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003541
3542 *usec = (long)((tval - intval) * EXTRACT_TIME_PRECISION);
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 if (*usec < 0)
3544 /* If rounding gave us a negative number,
3545 truncate. */
3546 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003547 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 }
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003549#if SIZEOF_TIME_T > SIZEOF_LONG
3550 intval = PyLong_AsUnsignedLongLongMask(t);
3551#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003552 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003553#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003554 if (intval == -1 && PyErr_Occurred())
3555 return -1;
3556 *sec = intval;
3557 *usec = 0;
3558 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003559}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003561PyDoc_STRVAR(posix_utime__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003562"utime(path[, (atime, mtime)])\n\
3563Set the access and modified time of the file to the given values.\n\
3564If no second argument is used, set the access and modified times to\n\
3565the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003566
Barry Warsaw53699e91996-12-10 23:23:01 +00003567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003568posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003569{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003570#ifdef MS_WINDOWS
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003571 PyObject *arg = Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003572 PyObject *obwpath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003573 wchar_t *wpath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003574 const char *apath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003576 time_t atimesec, mtimesec;
3577 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 FILETIME atime, mtime;
3579 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003580
Brian Curtin52fbea12011-11-06 13:41:17 -06003581 if (PyArg_ParseTuple(args, "U|O:utime", &obwpath, &arg)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003582 wpath = PyUnicode_AsUnicode(obwpath);
3583 if (wpath == NULL)
3584 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 Py_BEGIN_ALLOW_THREADS
3586 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3587 NULL, OPEN_EXISTING,
3588 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3589 Py_END_ALLOW_THREADS
3590 if (hFile == INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003591 return win32_error_object("utime", obwpath);
3592 }
3593 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 /* Drop the argument parsing error as narrow strings
3595 are also valid. */
3596 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003597
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003598 if (!PyArg_ParseTuple(args, "y|O:utime", &apath, &arg))
3599 return NULL;
3600 if (win32_warn_bytes_api())
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003602
Victor Stinner8c62be82010-05-06 00:08:46 +00003603 Py_BEGIN_ALLOW_THREADS
3604 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3605 NULL, OPEN_EXISTING,
3606 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3607 Py_END_ALLOW_THREADS
3608 if (hFile == INVALID_HANDLE_VALUE) {
3609 win32_error("utime", apath);
Victor Stinner8c62be82010-05-06 00:08:46 +00003610 return NULL;
3611 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 }
3613
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003614 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003615 SYSTEMTIME now;
3616 GetSystemTime(&now);
3617 if (!SystemTimeToFileTime(&now, &mtime) ||
3618 !SystemTimeToFileTime(&now, &atime)) {
3619 win32_error("utime", NULL);
3620 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003621 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 }
3623 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3624 PyErr_SetString(PyExc_TypeError,
3625 "utime() arg 2 must be a tuple (atime, mtime)");
3626 goto done;
3627 }
3628 else {
3629 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3630 &atimesec, &ausec) == -1)
3631 goto done;
3632 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3633 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3634 &mtimesec, &musec) == -1)
3635 goto done;
3636 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3637 }
3638 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3639 /* Avoid putting the file name into the error here,
3640 as that may confuse the user into believing that
3641 something is wrong with the file, when it also
3642 could be the time stamp that gives a problem. */
3643 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003644 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 }
3646 Py_INCREF(Py_None);
3647 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003648done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 CloseHandle(hFile);
3650 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003651#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003652
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 PyObject *opath;
3654 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003655 time_t atime, mtime;
3656 long ausec, musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 int res;
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003658 PyObject* arg = Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003659
Brian Curtin52fbea12011-11-06 13:41:17 -06003660 if (!PyArg_ParseTuple(args, "O&|O:utime",
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 PyUnicode_FSConverter, &opath, &arg))
3662 return NULL;
3663 path = PyBytes_AsString(opath);
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003664 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 /* optional time values not given */
3666 Py_BEGIN_ALLOW_THREADS
3667 res = utime(path, NULL);
3668 Py_END_ALLOW_THREADS
3669 }
3670 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3671 PyErr_SetString(PyExc_TypeError,
3672 "utime() arg 2 must be a tuple (atime, mtime)");
3673 Py_DECREF(opath);
3674 return NULL;
3675 }
3676 else {
3677 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3678 &atime, &ausec) == -1) {
3679 Py_DECREF(opath);
3680 return NULL;
3681 }
3682 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3683 &mtime, &musec) == -1) {
3684 Py_DECREF(opath);
3685 return NULL;
3686 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003687
3688 Py_BEGIN_ALLOW_THREADS
3689 {
3690#ifdef HAVE_UTIMENSAT
3691 struct timespec buf[2];
3692 buf[0].tv_sec = atime;
3693 buf[0].tv_nsec = ausec;
3694 buf[1].tv_sec = mtime;
3695 buf[1].tv_nsec = musec;
3696 res = utimensat(AT_FDCWD, path, buf, 0);
3697#elif defined(HAVE_UTIMES)
3698 struct timeval buf[2];
3699 buf[0].tv_sec = atime;
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 buf[0].tv_usec = ausec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003701 buf[1].tv_sec = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00003702 buf[1].tv_usec = musec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 res = utimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003704#elif defined(HAVE_UTIME_H)
3705 /* XXX should define struct utimbuf instead, above */
3706 struct utimbuf buf;
3707 buf.actime = atime;
3708 buf.modtime = mtime;
3709 res = utime(path, &buf);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003710#else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003711 time_t buf[2];
3712 buf[0] = atime;
3713 buf[1] = mtime;
3714 res = utime(path, buf);
3715#endif
3716 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003717 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003718 }
3719 if (res < 0) {
3720 return posix_error_with_allocated_filename(opath);
3721 }
3722 Py_DECREF(opath);
3723 Py_INCREF(Py_None);
3724 return Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003725#undef UTIME_EXTRACT
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003726#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003727}
3728
Ross Lagerwall7807c352011-03-17 20:20:30 +02003729#ifdef HAVE_FUTIMES
3730PyDoc_STRVAR(posix_futimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003731"futimes(fd[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003732Set the access and modified time of the file specified by the file\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003733descriptor fd to the given values. If no second argument is used, set the\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003734access and modified times to the current time.");
3735
3736static PyObject *
3737posix_futimes(PyObject *self, PyObject *args)
3738{
3739 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003740 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003741 time_t atime, mtime;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003742 long ausec, musec;
3743
Brian Curtinc1b65d12011-11-07 14:18:54 -06003744 if (!PyArg_ParseTuple(args, "i|O:futimes", &fd, &arg))
Ross Lagerwall7807c352011-03-17 20:20:30 +02003745 return NULL;
3746
3747 if (arg == Py_None) {
3748 /* optional time values not given */
3749 Py_BEGIN_ALLOW_THREADS
3750 res = futimes(fd, NULL);
3751 Py_END_ALLOW_THREADS
3752 }
3753 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3754 PyErr_SetString(PyExc_TypeError,
3755 "futimes() arg 2 must be a tuple (atime, mtime)");
3756 return NULL;
3757 }
3758 else {
3759 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003760 &atime, &ausec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003761 return NULL;
3762 }
3763 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003764 &mtime, &musec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003765 return NULL;
3766 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003767 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003768 {
3769#ifdef HAVE_FUTIMENS
3770 struct timespec buf[2];
3771 buf[0].tv_sec = atime;
3772 buf[0].tv_nsec = ausec;
3773 buf[1].tv_sec = mtime;
3774 buf[1].tv_nsec = musec;
3775 res = futimens(fd, buf);
3776#else
3777 struct timeval buf[2];
3778 buf[0].tv_sec = atime;
3779 buf[0].tv_usec = ausec;
3780 buf[1].tv_sec = mtime;
3781 buf[1].tv_usec = musec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003782 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003783#endif
3784 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003785 Py_END_ALLOW_THREADS
3786 }
3787 if (res < 0)
3788 return posix_error();
3789 Py_RETURN_NONE;
3790}
3791#endif
3792
3793#ifdef HAVE_LUTIMES
3794PyDoc_STRVAR(posix_lutimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003795"lutimes(path[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003796Like utime(), but if path is a symbolic link, it is not dereferenced.");
3797
3798static PyObject *
3799posix_lutimes(PyObject *self, PyObject *args)
3800{
Brian Curtinc1b65d12011-11-07 14:18:54 -06003801 PyObject *opath;
3802 PyObject *arg = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003803 const char *path;
3804 int res;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003805 time_t atime, mtime;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003806 long ausec, musec;
3807
Brian Curtinc1b65d12011-11-07 14:18:54 -06003808 if (!PyArg_ParseTuple(args, "O&|O:lutimes",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003809 PyUnicode_FSConverter, &opath, &arg))
3810 return NULL;
3811 path = PyBytes_AsString(opath);
3812 if (arg == Py_None) {
3813 /* optional time values not given */
3814 Py_BEGIN_ALLOW_THREADS
3815 res = lutimes(path, NULL);
3816 Py_END_ALLOW_THREADS
3817 }
3818 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3819 PyErr_SetString(PyExc_TypeError,
3820 "lutimes() arg 2 must be a tuple (atime, mtime)");
3821 Py_DECREF(opath);
3822 return NULL;
3823 }
3824 else {
3825 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003826 &atime, &ausec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003827 Py_DECREF(opath);
3828 return NULL;
3829 }
3830 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003831 &mtime, &musec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003832 Py_DECREF(opath);
3833 return NULL;
3834 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003835 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003836 {
3837#ifdef HAVE_UTIMENSAT
3838 struct timespec buf[2];
3839 buf[0].tv_sec = atime;
3840 buf[0].tv_nsec = ausec;
3841 buf[1].tv_sec = mtime;
3842 buf[1].tv_nsec = musec;
3843 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3844#else
3845 struct timeval buf[2];
3846 buf[0].tv_sec = atime;
3847 buf[0].tv_usec = ausec;
3848 buf[1].tv_sec = mtime;
3849 buf[1].tv_usec = musec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003850 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003851#endif
3852 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003853 Py_END_ALLOW_THREADS
3854 }
3855 Py_DECREF(opath);
3856 if (res < 0)
3857 return posix_error();
3858 Py_RETURN_NONE;
3859}
3860#endif
3861
3862#ifdef HAVE_FUTIMENS
3863PyDoc_STRVAR(posix_futimens__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003864"futimens(fd[, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003865Updates the timestamps of a file specified by the file descriptor fd, with\n\
3866nanosecond precision.\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003867If no second argument is given, set atime and mtime to the current time.\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003868If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
3869current time.\n\
3870If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
3871
3872static PyObject *
3873posix_futimens(PyObject *self, PyObject *args)
3874{
3875 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003876 PyObject *atime = Py_None;
3877 PyObject *mtime = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003878 struct timespec buf[2];
3879
Brian Curtinc1b65d12011-11-07 14:18:54 -06003880 if (!PyArg_ParseTuple(args, "i|OO:futimens",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003881 &fd, &atime, &mtime))
3882 return NULL;
3883 if (atime == Py_None && mtime == Py_None) {
3884 /* optional time values not given */
3885 Py_BEGIN_ALLOW_THREADS
3886 res = futimens(fd, NULL);
3887 Py_END_ALLOW_THREADS
3888 }
3889 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
3890 PyErr_SetString(PyExc_TypeError,
3891 "futimens() arg 2 must be a tuple (atime_sec, atime_nsec)");
3892 return NULL;
3893 }
3894 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
3895 PyErr_SetString(PyExc_TypeError,
3896 "futimens() arg 3 must be a tuple (mtime_sec, mtime_nsec)");
3897 return NULL;
3898 }
3899 else {
3900 if (!PyArg_ParseTuple(atime, "ll:futimens",
3901 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
3902 return NULL;
3903 }
3904 if (!PyArg_ParseTuple(mtime, "ll:futimens",
3905 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
3906 return NULL;
3907 }
3908 Py_BEGIN_ALLOW_THREADS
3909 res = futimens(fd, buf);
3910 Py_END_ALLOW_THREADS
3911 }
3912 if (res < 0)
3913 return posix_error();
3914 Py_RETURN_NONE;
3915}
3916#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003917
Guido van Rossum3b066191991-06-04 19:40:25 +00003918/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003919
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003920PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003921"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003922Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003923
Barry Warsaw53699e91996-12-10 23:23:01 +00003924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003925posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003926{
Victor Stinner8c62be82010-05-06 00:08:46 +00003927 int sts;
3928 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3929 return NULL;
3930 _exit(sts);
3931 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003932}
3933
Martin v. Löwis114619e2002-10-07 06:44:21 +00003934#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3935static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003936free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003937{
Victor Stinner8c62be82010-05-06 00:08:46 +00003938 Py_ssize_t i;
3939 for (i = 0; i < count; i++)
3940 PyMem_Free(array[i]);
3941 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003942}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003943
Antoine Pitrou69f71142009-05-24 21:25:49 +00003944static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003945int fsconvert_strdup(PyObject *o, char**out)
3946{
Victor Stinner8c62be82010-05-06 00:08:46 +00003947 PyObject *bytes;
3948 Py_ssize_t size;
3949 if (!PyUnicode_FSConverter(o, &bytes))
3950 return 0;
3951 size = PyBytes_GET_SIZE(bytes);
3952 *out = PyMem_Malloc(size+1);
3953 if (!*out)
3954 return 0;
3955 memcpy(*out, PyBytes_AsString(bytes), size+1);
3956 Py_DECREF(bytes);
3957 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003958}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003959#endif
3960
Ross Lagerwall7807c352011-03-17 20:20:30 +02003961#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00003962static char**
3963parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3964{
Victor Stinner8c62be82010-05-06 00:08:46 +00003965 char **envlist;
3966 Py_ssize_t i, pos, envc;
3967 PyObject *keys=NULL, *vals=NULL;
3968 PyObject *key, *val, *key2, *val2;
3969 char *p, *k, *v;
3970 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003971
Victor Stinner8c62be82010-05-06 00:08:46 +00003972 i = PyMapping_Size(env);
3973 if (i < 0)
3974 return NULL;
3975 envlist = PyMem_NEW(char *, i + 1);
3976 if (envlist == NULL) {
3977 PyErr_NoMemory();
3978 return NULL;
3979 }
3980 envc = 0;
3981 keys = PyMapping_Keys(env);
3982 vals = PyMapping_Values(env);
3983 if (!keys || !vals)
3984 goto error;
3985 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3986 PyErr_Format(PyExc_TypeError,
3987 "env.keys() or env.values() is not a list");
3988 goto error;
3989 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003990
Victor Stinner8c62be82010-05-06 00:08:46 +00003991 for (pos = 0; pos < i; pos++) {
3992 key = PyList_GetItem(keys, pos);
3993 val = PyList_GetItem(vals, pos);
3994 if (!key || !val)
3995 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003996
Victor Stinner8c62be82010-05-06 00:08:46 +00003997 if (PyUnicode_FSConverter(key, &key2) == 0)
3998 goto error;
3999 if (PyUnicode_FSConverter(val, &val2) == 0) {
4000 Py_DECREF(key2);
4001 goto error;
4002 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004003
4004#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4006 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004007#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004008 k = PyBytes_AsString(key2);
4009 v = PyBytes_AsString(val2);
4010 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004011
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 p = PyMem_NEW(char, len);
4013 if (p == NULL) {
4014 PyErr_NoMemory();
4015 Py_DECREF(key2);
4016 Py_DECREF(val2);
4017 goto error;
4018 }
4019 PyOS_snprintf(p, len, "%s=%s", k, v);
4020 envlist[envc++] = p;
4021 Py_DECREF(key2);
4022 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004023#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004025#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 }
4027 Py_DECREF(vals);
4028 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004029
Victor Stinner8c62be82010-05-06 00:08:46 +00004030 envlist[envc] = 0;
4031 *envc_ptr = envc;
4032 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004033
4034error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004035 Py_XDECREF(keys);
4036 Py_XDECREF(vals);
4037 while (--envc >= 0)
4038 PyMem_DEL(envlist[envc]);
4039 PyMem_DEL(envlist);
4040 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004041}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004042
Ross Lagerwall7807c352011-03-17 20:20:30 +02004043static char**
4044parse_arglist(PyObject* argv, Py_ssize_t *argc)
4045{
4046 int i;
4047 char **argvlist = PyMem_NEW(char *, *argc+1);
4048 if (argvlist == NULL) {
4049 PyErr_NoMemory();
4050 return NULL;
4051 }
4052 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004053 PyObject* item = PySequence_ITEM(argv, i);
4054 if (item == NULL)
4055 goto fail;
4056 if (!fsconvert_strdup(item, &argvlist[i])) {
4057 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004058 goto fail;
4059 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004060 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004061 }
4062 argvlist[*argc] = NULL;
4063 return argvlist;
4064fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004065 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004066 free_string_array(argvlist, *argc);
4067 return NULL;
4068}
4069#endif
4070
4071#ifdef HAVE_EXECV
4072PyDoc_STRVAR(posix_execv__doc__,
4073"execv(path, args)\n\n\
4074Execute an executable path with arguments, replacing current process.\n\
4075\n\
4076 path: path of executable file\n\
4077 args: tuple or list of strings");
4078
4079static PyObject *
4080posix_execv(PyObject *self, PyObject *args)
4081{
4082 PyObject *opath;
4083 char *path;
4084 PyObject *argv;
4085 char **argvlist;
4086 Py_ssize_t argc;
4087
4088 /* execv has two arguments: (path, argv), where
4089 argv is a list or tuple of strings. */
4090
4091 if (!PyArg_ParseTuple(args, "O&O:execv",
4092 PyUnicode_FSConverter,
4093 &opath, &argv))
4094 return NULL;
4095 path = PyBytes_AsString(opath);
4096 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4097 PyErr_SetString(PyExc_TypeError,
4098 "execv() arg 2 must be a tuple or list");
4099 Py_DECREF(opath);
4100 return NULL;
4101 }
4102 argc = PySequence_Size(argv);
4103 if (argc < 1) {
4104 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4105 Py_DECREF(opath);
4106 return NULL;
4107 }
4108
4109 argvlist = parse_arglist(argv, &argc);
4110 if (argvlist == NULL) {
4111 Py_DECREF(opath);
4112 return NULL;
4113 }
4114
4115 execv(path, argvlist);
4116
4117 /* If we get here it's definitely an error */
4118
4119 free_string_array(argvlist, argc);
4120 Py_DECREF(opath);
4121 return posix_error();
4122}
4123
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004124PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004125"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004126Execute a path with arguments and environment, replacing current process.\n\
4127\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004128 path: path of executable file\n\
4129 args: tuple or list of arguments\n\
4130 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004131
Barry Warsaw53699e91996-12-10 23:23:01 +00004132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004133posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004134{
Victor Stinner8c62be82010-05-06 00:08:46 +00004135 PyObject *opath;
4136 char *path;
4137 PyObject *argv, *env;
4138 char **argvlist;
4139 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004140 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004141
Victor Stinner8c62be82010-05-06 00:08:46 +00004142 /* execve has three arguments: (path, argv, env), where
4143 argv is a list or tuple of strings and env is a dictionary
4144 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004145
Victor Stinner8c62be82010-05-06 00:08:46 +00004146 if (!PyArg_ParseTuple(args, "O&OO:execve",
4147 PyUnicode_FSConverter,
4148 &opath, &argv, &env))
4149 return NULL;
4150 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004151 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004152 PyErr_SetString(PyExc_TypeError,
4153 "execve() arg 2 must be a tuple or list");
4154 goto fail_0;
4155 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004156 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004157 if (!PyMapping_Check(env)) {
4158 PyErr_SetString(PyExc_TypeError,
4159 "execve() arg 3 must be a mapping object");
4160 goto fail_0;
4161 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004162
Ross Lagerwall7807c352011-03-17 20:20:30 +02004163 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004165 goto fail_0;
4166 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004167
Victor Stinner8c62be82010-05-06 00:08:46 +00004168 envlist = parse_envlist(env, &envc);
4169 if (envlist == NULL)
4170 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004171
Victor Stinner8c62be82010-05-06 00:08:46 +00004172 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004173
Victor Stinner8c62be82010-05-06 00:08:46 +00004174 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004175
Victor Stinner8c62be82010-05-06 00:08:46 +00004176 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004177
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 while (--envc >= 0)
4179 PyMem_DEL(envlist[envc]);
4180 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004181 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004182 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004183 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004184 Py_DECREF(opath);
4185 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004186}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004187#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004188
Ross Lagerwall7807c352011-03-17 20:20:30 +02004189#ifdef HAVE_FEXECVE
4190PyDoc_STRVAR(posix_fexecve__doc__,
4191"fexecve(fd, args, env)\n\n\
4192Execute the program specified by a file descriptor with arguments and\n\
4193environment, replacing the current process.\n\
4194\n\
4195 fd: file descriptor of executable\n\
4196 args: tuple or list of arguments\n\
4197 env: dictionary of strings mapping to strings");
4198
4199static PyObject *
4200posix_fexecve(PyObject *self, PyObject *args)
4201{
4202 int fd;
4203 PyObject *argv, *env;
4204 char **argvlist;
4205 char **envlist;
4206 Py_ssize_t argc, envc;
4207
4208 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4209 &fd, &argv, &env))
4210 return NULL;
4211 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4212 PyErr_SetString(PyExc_TypeError,
4213 "fexecve() arg 2 must be a tuple or list");
4214 return NULL;
4215 }
4216 argc = PySequence_Size(argv);
4217 if (!PyMapping_Check(env)) {
4218 PyErr_SetString(PyExc_TypeError,
4219 "fexecve() arg 3 must be a mapping object");
4220 return NULL;
4221 }
4222
4223 argvlist = parse_arglist(argv, &argc);
4224 if (argvlist == NULL)
4225 return NULL;
4226
4227 envlist = parse_envlist(env, &envc);
4228 if (envlist == NULL)
4229 goto fail;
4230
4231 fexecve(fd, argvlist, envlist);
4232
4233 /* If we get here it's definitely an error */
4234
4235 (void) posix_error();
4236
4237 while (--envc >= 0)
4238 PyMem_DEL(envlist[envc]);
4239 PyMem_DEL(envlist);
4240 fail:
4241 free_string_array(argvlist, argc);
4242 return NULL;
4243}
4244#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004245
Guido van Rossuma1065681999-01-25 23:20:23 +00004246#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004247PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004248"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004249Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004250\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004251 mode: mode of process creation\n\
4252 path: path of executable file\n\
4253 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004254
4255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004256posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004257{
Victor Stinner8c62be82010-05-06 00:08:46 +00004258 PyObject *opath;
4259 char *path;
4260 PyObject *argv;
4261 char **argvlist;
4262 int mode, i;
4263 Py_ssize_t argc;
4264 Py_intptr_t spawnval;
4265 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004266
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 /* spawnv has three arguments: (mode, path, argv), where
4268 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004269
Victor Stinner8c62be82010-05-06 00:08:46 +00004270 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4271 PyUnicode_FSConverter,
4272 &opath, &argv))
4273 return NULL;
4274 path = PyBytes_AsString(opath);
4275 if (PyList_Check(argv)) {
4276 argc = PyList_Size(argv);
4277 getitem = PyList_GetItem;
4278 }
4279 else if (PyTuple_Check(argv)) {
4280 argc = PyTuple_Size(argv);
4281 getitem = PyTuple_GetItem;
4282 }
4283 else {
4284 PyErr_SetString(PyExc_TypeError,
4285 "spawnv() arg 2 must be a tuple or list");
4286 Py_DECREF(opath);
4287 return NULL;
4288 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004289
Victor Stinner8c62be82010-05-06 00:08:46 +00004290 argvlist = PyMem_NEW(char *, argc+1);
4291 if (argvlist == NULL) {
4292 Py_DECREF(opath);
4293 return PyErr_NoMemory();
4294 }
4295 for (i = 0; i < argc; i++) {
4296 if (!fsconvert_strdup((*getitem)(argv, i),
4297 &argvlist[i])) {
4298 free_string_array(argvlist, i);
4299 PyErr_SetString(
4300 PyExc_TypeError,
4301 "spawnv() arg 2 must contain only strings");
4302 Py_DECREF(opath);
4303 return NULL;
4304 }
4305 }
4306 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004307
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004308#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004309 Py_BEGIN_ALLOW_THREADS
4310 spawnval = spawnv(mode, path, argvlist);
4311 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004312#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004313 if (mode == _OLD_P_OVERLAY)
4314 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004315
Victor Stinner8c62be82010-05-06 00:08:46 +00004316 Py_BEGIN_ALLOW_THREADS
4317 spawnval = _spawnv(mode, path, argvlist);
4318 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004319#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004320
Victor Stinner8c62be82010-05-06 00:08:46 +00004321 free_string_array(argvlist, argc);
4322 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004323
Victor Stinner8c62be82010-05-06 00:08:46 +00004324 if (spawnval == -1)
4325 return posix_error();
4326 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004327#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004328 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004329#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004330 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004331#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004332}
4333
4334
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004335PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004336"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004337Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004338\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004339 mode: mode of process creation\n\
4340 path: path of executable file\n\
4341 args: tuple or list of arguments\n\
4342 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004343
4344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004345posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004346{
Victor Stinner8c62be82010-05-06 00:08:46 +00004347 PyObject *opath;
4348 char *path;
4349 PyObject *argv, *env;
4350 char **argvlist;
4351 char **envlist;
4352 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004353 int mode;
4354 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004355 Py_intptr_t spawnval;
4356 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4357 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004358
Victor Stinner8c62be82010-05-06 00:08:46 +00004359 /* spawnve has four arguments: (mode, path, argv, env), where
4360 argv is a list or tuple of strings and env is a dictionary
4361 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004362
Victor Stinner8c62be82010-05-06 00:08:46 +00004363 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4364 PyUnicode_FSConverter,
4365 &opath, &argv, &env))
4366 return NULL;
4367 path = PyBytes_AsString(opath);
4368 if (PyList_Check(argv)) {
4369 argc = PyList_Size(argv);
4370 getitem = PyList_GetItem;
4371 }
4372 else if (PyTuple_Check(argv)) {
4373 argc = PyTuple_Size(argv);
4374 getitem = PyTuple_GetItem;
4375 }
4376 else {
4377 PyErr_SetString(PyExc_TypeError,
4378 "spawnve() arg 2 must be a tuple or list");
4379 goto fail_0;
4380 }
4381 if (!PyMapping_Check(env)) {
4382 PyErr_SetString(PyExc_TypeError,
4383 "spawnve() arg 3 must be a mapping object");
4384 goto fail_0;
4385 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004386
Victor Stinner8c62be82010-05-06 00:08:46 +00004387 argvlist = PyMem_NEW(char *, argc+1);
4388 if (argvlist == NULL) {
4389 PyErr_NoMemory();
4390 goto fail_0;
4391 }
4392 for (i = 0; i < argc; i++) {
4393 if (!fsconvert_strdup((*getitem)(argv, i),
4394 &argvlist[i]))
4395 {
4396 lastarg = i;
4397 goto fail_1;
4398 }
4399 }
4400 lastarg = argc;
4401 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004402
Victor Stinner8c62be82010-05-06 00:08:46 +00004403 envlist = parse_envlist(env, &envc);
4404 if (envlist == NULL)
4405 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004406
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004407#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004408 Py_BEGIN_ALLOW_THREADS
4409 spawnval = spawnve(mode, path, argvlist, envlist);
4410 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004411#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004412 if (mode == _OLD_P_OVERLAY)
4413 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004414
Victor Stinner8c62be82010-05-06 00:08:46 +00004415 Py_BEGIN_ALLOW_THREADS
4416 spawnval = _spawnve(mode, path, argvlist, envlist);
4417 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004418#endif
Tim Peters25059d32001-12-07 20:35:43 +00004419
Victor Stinner8c62be82010-05-06 00:08:46 +00004420 if (spawnval == -1)
4421 (void) posix_error();
4422 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004423#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004424 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004425#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004426 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004427#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004428
Victor Stinner8c62be82010-05-06 00:08:46 +00004429 while (--envc >= 0)
4430 PyMem_DEL(envlist[envc]);
4431 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004432 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004433 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004434 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004435 Py_DECREF(opath);
4436 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004437}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004438
4439/* OS/2 supports spawnvp & spawnvpe natively */
4440#if defined(PYOS_OS2)
4441PyDoc_STRVAR(posix_spawnvp__doc__,
4442"spawnvp(mode, file, args)\n\n\
4443Execute the program 'file' in a new process, using the environment\n\
4444search path to find the file.\n\
4445\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004446 mode: mode of process creation\n\
4447 file: executable file name\n\
4448 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004449
4450static PyObject *
4451posix_spawnvp(PyObject *self, PyObject *args)
4452{
Victor Stinner8c62be82010-05-06 00:08:46 +00004453 PyObject *opath;
4454 char *path;
4455 PyObject *argv;
4456 char **argvlist;
4457 int mode, i, argc;
4458 Py_intptr_t spawnval;
4459 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004460
Victor Stinner8c62be82010-05-06 00:08:46 +00004461 /* spawnvp has three arguments: (mode, path, argv), where
4462 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004463
Victor Stinner8c62be82010-05-06 00:08:46 +00004464 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4465 PyUnicode_FSConverter,
4466 &opath, &argv))
4467 return NULL;
4468 path = PyBytes_AsString(opath);
4469 if (PyList_Check(argv)) {
4470 argc = PyList_Size(argv);
4471 getitem = PyList_GetItem;
4472 }
4473 else if (PyTuple_Check(argv)) {
4474 argc = PyTuple_Size(argv);
4475 getitem = PyTuple_GetItem;
4476 }
4477 else {
4478 PyErr_SetString(PyExc_TypeError,
4479 "spawnvp() arg 2 must be a tuple or list");
4480 Py_DECREF(opath);
4481 return NULL;
4482 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004483
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 argvlist = PyMem_NEW(char *, argc+1);
4485 if (argvlist == NULL) {
4486 Py_DECREF(opath);
4487 return PyErr_NoMemory();
4488 }
4489 for (i = 0; i < argc; i++) {
4490 if (!fsconvert_strdup((*getitem)(argv, i),
4491 &argvlist[i])) {
4492 free_string_array(argvlist, i);
4493 PyErr_SetString(
4494 PyExc_TypeError,
4495 "spawnvp() arg 2 must contain only strings");
4496 Py_DECREF(opath);
4497 return NULL;
4498 }
4499 }
4500 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004501
Victor Stinner8c62be82010-05-06 00:08:46 +00004502 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004503#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004504 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004505#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004506 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004507#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004509
Victor Stinner8c62be82010-05-06 00:08:46 +00004510 free_string_array(argvlist, argc);
4511 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004512
Victor Stinner8c62be82010-05-06 00:08:46 +00004513 if (spawnval == -1)
4514 return posix_error();
4515 else
4516 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004517}
4518
4519
4520PyDoc_STRVAR(posix_spawnvpe__doc__,
4521"spawnvpe(mode, file, args, env)\n\n\
4522Execute the program 'file' in a new process, using the environment\n\
4523search path to find the file.\n\
4524\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004525 mode: mode of process creation\n\
4526 file: executable file name\n\
4527 args: tuple or list of arguments\n\
4528 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004529
4530static PyObject *
4531posix_spawnvpe(PyObject *self, PyObject *args)
4532{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02004533 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00004534 char *path;
4535 PyObject *argv, *env;
4536 char **argvlist;
4537 char **envlist;
4538 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004539 int mode;
4540 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004541 Py_intptr_t spawnval;
4542 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4543 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004544
Victor Stinner8c62be82010-05-06 00:08:46 +00004545 /* spawnvpe has four arguments: (mode, path, argv, env), where
4546 argv is a list or tuple of strings and env is a dictionary
4547 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004548
Victor Stinner8c62be82010-05-06 00:08:46 +00004549 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4550 PyUnicode_FSConverter,
4551 &opath, &argv, &env))
4552 return NULL;
4553 path = PyBytes_AsString(opath);
4554 if (PyList_Check(argv)) {
4555 argc = PyList_Size(argv);
4556 getitem = PyList_GetItem;
4557 }
4558 else if (PyTuple_Check(argv)) {
4559 argc = PyTuple_Size(argv);
4560 getitem = PyTuple_GetItem;
4561 }
4562 else {
4563 PyErr_SetString(PyExc_TypeError,
4564 "spawnvpe() arg 2 must be a tuple or list");
4565 goto fail_0;
4566 }
4567 if (!PyMapping_Check(env)) {
4568 PyErr_SetString(PyExc_TypeError,
4569 "spawnvpe() arg 3 must be a mapping object");
4570 goto fail_0;
4571 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004572
Victor Stinner8c62be82010-05-06 00:08:46 +00004573 argvlist = PyMem_NEW(char *, argc+1);
4574 if (argvlist == NULL) {
4575 PyErr_NoMemory();
4576 goto fail_0;
4577 }
4578 for (i = 0; i < argc; i++) {
4579 if (!fsconvert_strdup((*getitem)(argv, i),
4580 &argvlist[i]))
4581 {
4582 lastarg = i;
4583 goto fail_1;
4584 }
4585 }
4586 lastarg = argc;
4587 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004588
Victor Stinner8c62be82010-05-06 00:08:46 +00004589 envlist = parse_envlist(env, &envc);
4590 if (envlist == NULL)
4591 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004592
Victor Stinner8c62be82010-05-06 00:08:46 +00004593 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004594#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004595 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004596#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004597 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004598#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004599 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004600
Victor Stinner8c62be82010-05-06 00:08:46 +00004601 if (spawnval == -1)
4602 (void) posix_error();
4603 else
4604 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004605
Victor Stinner8c62be82010-05-06 00:08:46 +00004606 while (--envc >= 0)
4607 PyMem_DEL(envlist[envc]);
4608 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004609 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004610 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004611 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004612 Py_DECREF(opath);
4613 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004614}
4615#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004616#endif /* HAVE_SPAWNV */
4617
4618
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004619#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004620PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004621"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004622Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4623\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004624Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004625
4626static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004627posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004628{
Victor Stinner8c62be82010-05-06 00:08:46 +00004629 pid_t pid;
4630 int result = 0;
4631 _PyImport_AcquireLock();
4632 pid = fork1();
4633 if (pid == 0) {
4634 /* child: this clobbers and resets the import lock. */
4635 PyOS_AfterFork();
4636 } else {
4637 /* parent: release the import lock. */
4638 result = _PyImport_ReleaseLock();
4639 }
4640 if (pid == -1)
4641 return posix_error();
4642 if (result < 0) {
4643 /* Don't clobber the OSError if the fork failed. */
4644 PyErr_SetString(PyExc_RuntimeError,
4645 "not holding the import lock");
4646 return NULL;
4647 }
4648 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004649}
4650#endif
4651
4652
Guido van Rossumad0ee831995-03-01 10:34:45 +00004653#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004654PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004655"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004656Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004657Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004658
Barry Warsaw53699e91996-12-10 23:23:01 +00004659static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004660posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004661{
Victor Stinner8c62be82010-05-06 00:08:46 +00004662 pid_t pid;
4663 int result = 0;
4664 _PyImport_AcquireLock();
4665 pid = fork();
4666 if (pid == 0) {
4667 /* child: this clobbers and resets the import lock. */
4668 PyOS_AfterFork();
4669 } else {
4670 /* parent: release the import lock. */
4671 result = _PyImport_ReleaseLock();
4672 }
4673 if (pid == -1)
4674 return posix_error();
4675 if (result < 0) {
4676 /* Don't clobber the OSError if the fork failed. */
4677 PyErr_SetString(PyExc_RuntimeError,
4678 "not holding the import lock");
4679 return NULL;
4680 }
4681 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004682}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004683#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004684
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004685#ifdef HAVE_SCHED_H
4686
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004687#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4688
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004689PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4690"sched_get_priority_max(policy)\n\n\
4691Get the maximum scheduling priority for *policy*.");
4692
4693static PyObject *
4694posix_sched_get_priority_max(PyObject *self, PyObject *args)
4695{
4696 int policy, max;
4697
4698 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4699 return NULL;
4700 max = sched_get_priority_max(policy);
4701 if (max < 0)
4702 return posix_error();
4703 return PyLong_FromLong(max);
4704}
4705
4706PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4707"sched_get_priority_min(policy)\n\n\
4708Get the minimum scheduling priority for *policy*.");
4709
4710static PyObject *
4711posix_sched_get_priority_min(PyObject *self, PyObject *args)
4712{
4713 int policy, min;
4714
4715 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4716 return NULL;
4717 min = sched_get_priority_min(policy);
4718 if (min < 0)
4719 return posix_error();
4720 return PyLong_FromLong(min);
4721}
4722
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004723#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4724
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004725#ifdef HAVE_SCHED_SETSCHEDULER
4726
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004727PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4728"sched_getscheduler(pid)\n\n\
4729Get the scheduling policy for the process with a PID of *pid*.\n\
4730Passing a PID of 0 returns the scheduling policy for the calling process.");
4731
4732static PyObject *
4733posix_sched_getscheduler(PyObject *self, PyObject *args)
4734{
4735 pid_t pid;
4736 int policy;
4737
4738 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4739 return NULL;
4740 policy = sched_getscheduler(pid);
4741 if (policy < 0)
4742 return posix_error();
4743 return PyLong_FromLong(policy);
4744}
4745
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004746#endif
4747
4748#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4749
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004750static PyObject *
4751sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4752{
4753 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004754 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004755
4756 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4757 return NULL;
4758 res = PyStructSequence_New(type);
4759 if (!res)
4760 return NULL;
4761 Py_INCREF(priority);
4762 PyStructSequence_SET_ITEM(res, 0, priority);
4763 return res;
4764}
4765
4766PyDoc_STRVAR(sched_param__doc__,
4767"sched_param(sched_priority): A scheduling parameter.\n\n\
4768Current has only one field: sched_priority");
4769
4770static PyStructSequence_Field sched_param_fields[] = {
4771 {"sched_priority", "the scheduling priority"},
4772 {0}
4773};
4774
4775static PyStructSequence_Desc sched_param_desc = {
4776 "sched_param", /* name */
4777 sched_param__doc__, /* doc */
4778 sched_param_fields,
4779 1
4780};
4781
4782static int
4783convert_sched_param(PyObject *param, struct sched_param *res)
4784{
4785 long priority;
4786
4787 if (Py_TYPE(param) != &SchedParamType) {
4788 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4789 return 0;
4790 }
4791 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4792 if (priority == -1 && PyErr_Occurred())
4793 return 0;
4794 if (priority > INT_MAX || priority < INT_MIN) {
4795 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4796 return 0;
4797 }
4798 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4799 return 1;
4800}
4801
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004802#endif
4803
4804#ifdef HAVE_SCHED_SETSCHEDULER
4805
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004806PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4807"sched_setscheduler(pid, policy, param)\n\n\
4808Set the scheduling policy, *policy*, for *pid*.\n\
4809If *pid* is 0, the calling process is changed.\n\
4810*param* is an instance of sched_param.");
4811
4812static PyObject *
4813posix_sched_setscheduler(PyObject *self, PyObject *args)
4814{
4815 pid_t pid;
4816 int policy;
4817 struct sched_param param;
4818
4819 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4820 &pid, &policy, &convert_sched_param, &param))
4821 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004822
4823 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004824 ** sched_setscheduler() returns 0 in Linux, but the previous
4825 ** scheduling policy under Solaris/Illumos, and others.
4826 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004827 */
4828 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004829 return posix_error();
4830 Py_RETURN_NONE;
4831}
4832
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004833#endif
4834
4835#ifdef HAVE_SCHED_SETPARAM
4836
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004837PyDoc_STRVAR(posix_sched_getparam__doc__,
4838"sched_getparam(pid) -> sched_param\n\n\
4839Returns scheduling parameters for the process with *pid* as an instance of the\n\
4840sched_param class. A PID of 0 means the calling process.");
4841
4842static PyObject *
4843posix_sched_getparam(PyObject *self, PyObject *args)
4844{
4845 pid_t pid;
4846 struct sched_param param;
4847 PyObject *res, *priority;
4848
4849 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4850 return NULL;
4851 if (sched_getparam(pid, &param))
4852 return posix_error();
4853 res = PyStructSequence_New(&SchedParamType);
4854 if (!res)
4855 return NULL;
4856 priority = PyLong_FromLong(param.sched_priority);
4857 if (!priority) {
4858 Py_DECREF(res);
4859 return NULL;
4860 }
4861 PyStructSequence_SET_ITEM(res, 0, priority);
4862 return res;
4863}
4864
4865PyDoc_STRVAR(posix_sched_setparam__doc__,
4866"sched_setparam(pid, param)\n\n\
4867Set scheduling parameters for a process with PID *pid*.\n\
4868A PID of 0 means the calling process.");
4869
4870static PyObject *
4871posix_sched_setparam(PyObject *self, PyObject *args)
4872{
4873 pid_t pid;
4874 struct sched_param param;
4875
4876 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4877 &pid, &convert_sched_param, &param))
4878 return NULL;
4879 if (sched_setparam(pid, &param))
4880 return posix_error();
4881 Py_RETURN_NONE;
4882}
4883
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004884#endif
4885
4886#ifdef HAVE_SCHED_RR_GET_INTERVAL
4887
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004888PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4889"sched_rr_get_interval(pid) -> float\n\n\
4890Return the round-robin quantum for the process with PID *pid* in seconds.");
4891
4892static PyObject *
4893posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4894{
4895 pid_t pid;
4896 struct timespec interval;
4897
4898 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4899 return NULL;
4900 if (sched_rr_get_interval(pid, &interval))
4901 return posix_error();
4902 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4903}
4904
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004905#endif
4906
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004907PyDoc_STRVAR(posix_sched_yield__doc__,
4908"sched_yield()\n\n\
4909Voluntarily relinquish the CPU.");
4910
4911static PyObject *
4912posix_sched_yield(PyObject *self, PyObject *noargs)
4913{
4914 if (sched_yield())
4915 return posix_error();
4916 Py_RETURN_NONE;
4917}
4918
Benjamin Peterson2740af82011-08-02 17:41:34 -05004919#ifdef HAVE_SCHED_SETAFFINITY
4920
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004921typedef struct {
4922 PyObject_HEAD;
4923 Py_ssize_t size;
4924 int ncpus;
4925 cpu_set_t *set;
4926} Py_cpu_set;
4927
4928static PyTypeObject cpu_set_type;
4929
4930static void
4931cpu_set_dealloc(Py_cpu_set *set)
4932{
4933 assert(set->set);
4934 CPU_FREE(set->set);
4935 Py_TYPE(set)->tp_free(set);
4936}
4937
4938static Py_cpu_set *
4939make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
4940{
4941 Py_cpu_set *set;
4942
4943 if (size < 0) {
4944 PyErr_SetString(PyExc_ValueError, "negative size");
4945 return NULL;
4946 }
4947 set = (Py_cpu_set *)type->tp_alloc(type, 0);
4948 if (!set)
4949 return NULL;
4950 set->ncpus = size;
4951 set->size = CPU_ALLOC_SIZE(size);
4952 set->set = CPU_ALLOC(size);
4953 if (!set->set) {
4954 type->tp_free(set);
4955 PyErr_NoMemory();
4956 return NULL;
4957 }
4958 CPU_ZERO_S(set->size, set->set);
4959 return set;
4960}
4961
4962static PyObject *
4963cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4964{
4965 int size;
4966
4967 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
4968 !PyArg_ParseTuple(args, "i:cpu_set", &size))
4969 return NULL;
4970 return (PyObject *)make_new_cpu_set(type, size);
4971}
4972
4973static PyObject *
4974cpu_set_repr(Py_cpu_set *set)
4975{
4976 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02004977}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004978
4979static Py_ssize_t
4980cpu_set_len(Py_cpu_set *set)
4981{
4982 return set->ncpus;
4983}
4984
4985static int
4986_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
4987{
4988 int cpu;
4989 if (!PyArg_ParseTuple(args, requester, &cpu))
4990 return -1;
4991 if (cpu < 0) {
4992 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
4993 return -1;
4994 }
4995 if (cpu >= set->ncpus) {
4996 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
4997 return -1;
4998 }
4999 return cpu;
5000}
5001
5002PyDoc_STRVAR(cpu_set_set_doc,
5003"cpu_set.set(i)\n\n\
5004Add CPU *i* to the set.");
5005
5006static PyObject *
5007cpu_set_set(Py_cpu_set *set, PyObject *args)
5008{
5009 int cpu = _get_cpu(set, "i|set", args);
5010 if (cpu == -1)
5011 return NULL;
5012 CPU_SET_S(cpu, set->size, set->set);
5013 Py_RETURN_NONE;
5014}
5015
5016PyDoc_STRVAR(cpu_set_count_doc,
5017"cpu_set.count() -> int\n\n\
5018Return the number of CPUs active in the set.");
5019
5020static PyObject *
5021cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5022{
5023 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5024}
5025
5026PyDoc_STRVAR(cpu_set_clear_doc,
5027"cpu_set.clear(i)\n\n\
5028Remove CPU *i* from the set.");
5029
5030static PyObject *
5031cpu_set_clear(Py_cpu_set *set, PyObject *args)
5032{
5033 int cpu = _get_cpu(set, "i|clear", args);
5034 if (cpu == -1)
5035 return NULL;
5036 CPU_CLR_S(cpu, set->size, set->set);
5037 Py_RETURN_NONE;
5038}
5039
5040PyDoc_STRVAR(cpu_set_isset_doc,
5041"cpu_set.isset(i) -> bool\n\n\
5042Test if CPU *i* is in the set.");
5043
5044static PyObject *
5045cpu_set_isset(Py_cpu_set *set, PyObject *args)
5046{
5047 int cpu = _get_cpu(set, "i|isset", args);
5048 if (cpu == -1)
5049 return NULL;
5050 if (CPU_ISSET_S(cpu, set->size, set->set))
5051 Py_RETURN_TRUE;
5052 Py_RETURN_FALSE;
5053}
5054
5055PyDoc_STRVAR(cpu_set_zero_doc,
5056"cpu_set.zero()\n\n\
5057Clear the cpu_set.");
5058
5059static PyObject *
5060cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5061{
5062 CPU_ZERO_S(set->size, set->set);
5063 Py_RETURN_NONE;
5064}
5065
5066static PyObject *
5067cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5068{
5069 int eq;
5070
Brian Curtindfc80e32011-08-10 20:28:54 -05005071 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5072 Py_RETURN_NOTIMPLEMENTED;
5073
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005074 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5075 if ((op == Py_EQ) ? eq : !eq)
5076 Py_RETURN_TRUE;
5077 else
5078 Py_RETURN_FALSE;
5079}
5080
5081#define CPU_SET_BINOP(name, op) \
5082 static PyObject * \
5083 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5084 if (res) { \
5085 Py_INCREF(res); \
5086 } \
5087 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005088 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005089 if (!res) \
5090 return NULL; \
5091 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005092 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005093 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005094 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005095 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005096 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005097 op(res->size, res->set, left->set, right->set); \
5098 return (PyObject *)res; \
5099 } \
5100 static PyObject * \
5101 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5102 return do_cpu_set_##name(left, right, NULL); \
5103 } \
5104 static PyObject * \
5105 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5106 return do_cpu_set_##name(left, right, left); \
5107 } \
5108
5109CPU_SET_BINOP(and, CPU_AND_S)
5110CPU_SET_BINOP(or, CPU_OR_S)
5111CPU_SET_BINOP(xor, CPU_XOR_S)
5112#undef CPU_SET_BINOP
5113
5114PyDoc_STRVAR(cpu_set_doc,
5115"cpu_set(size)\n\n\
5116Create an empty mask of CPUs.");
5117
5118static PyNumberMethods cpu_set_as_number = {
5119 0, /*nb_add*/
5120 0, /*nb_subtract*/
5121 0, /*nb_multiply*/
5122 0, /*nb_remainder*/
5123 0, /*nb_divmod*/
5124 0, /*nb_power*/
5125 0, /*nb_negative*/
5126 0, /*nb_positive*/
5127 0, /*nb_absolute*/
5128 0, /*nb_bool*/
5129 0, /*nb_invert*/
5130 0, /*nb_lshift*/
5131 0, /*nb_rshift*/
5132 (binaryfunc)cpu_set_and, /*nb_and*/
5133 (binaryfunc)cpu_set_xor, /*nb_xor*/
5134 (binaryfunc)cpu_set_or, /*nb_or*/
5135 0, /*nb_int*/
5136 0, /*nb_reserved*/
5137 0, /*nb_float*/
5138 0, /*nb_inplace_add*/
5139 0, /*nb_inplace_subtract*/
5140 0, /*nb_inplace_multiply*/
5141 0, /*nb_inplace_remainder*/
5142 0, /*nb_inplace_power*/
5143 0, /*nb_inplace_lshift*/
5144 0, /*nb_inplace_rshift*/
5145 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5146 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5147 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5148};
5149
5150static PySequenceMethods cpu_set_as_sequence = {
5151 (lenfunc)cpu_set_len, /* sq_length */
5152};
5153
5154static PyMethodDef cpu_set_methods[] = {
5155 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5156 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5157 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5158 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5159 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5160 {NULL, NULL} /* sentinel */
5161};
5162
5163static PyTypeObject cpu_set_type = {
5164 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5165 "posix.cpu_set", /* tp_name */
5166 sizeof(Py_cpu_set), /* tp_basicsize */
5167 0, /* tp_itemsize */
5168 /* methods */
5169 (destructor)cpu_set_dealloc, /* tp_dealloc */
5170 0, /* tp_print */
5171 0, /* tp_getattr */
5172 0, /* tp_setattr */
5173 0, /* tp_reserved */
5174 (reprfunc)cpu_set_repr, /* tp_repr */
5175 &cpu_set_as_number, /* tp_as_number */
5176 &cpu_set_as_sequence, /* tp_as_sequence */
5177 0, /* tp_as_mapping */
5178 PyObject_HashNotImplemented, /* tp_hash */
5179 0, /* tp_call */
5180 0, /* tp_str */
5181 PyObject_GenericGetAttr, /* tp_getattro */
5182 0, /* tp_setattro */
5183 0, /* tp_as_buffer */
5184 Py_TPFLAGS_DEFAULT, /* tp_flags */
5185 cpu_set_doc, /* tp_doc */
5186 0, /* tp_traverse */
5187 0, /* tp_clear */
5188 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5189 0, /* tp_weaklistoffset */
5190 0, /* tp_iter */
5191 0, /* tp_iternext */
5192 cpu_set_methods, /* tp_methods */
5193 0, /* tp_members */
5194 0, /* tp_getset */
5195 0, /* tp_base */
5196 0, /* tp_dict */
5197 0, /* tp_descr_get */
5198 0, /* tp_descr_set */
5199 0, /* tp_dictoffset */
5200 0, /* tp_init */
5201 PyType_GenericAlloc, /* tp_alloc */
5202 cpu_set_new, /* tp_new */
5203 PyObject_Del, /* tp_free */
5204};
5205
5206PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5207"sched_setaffinity(pid, cpu_set)\n\n\
5208Set the affinity of the process with PID *pid* to *cpu_set*.");
5209
5210static PyObject *
5211posix_sched_setaffinity(PyObject *self, PyObject *args)
5212{
5213 pid_t pid;
5214 Py_cpu_set *cpu_set;
5215
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005216 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005217 &pid, &cpu_set_type, &cpu_set))
5218 return NULL;
5219 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5220 return posix_error();
5221 Py_RETURN_NONE;
5222}
5223
5224PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5225"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5226Return the affinity of the process with PID *pid*.\n\
5227The returned cpu_set will be of size *ncpus*.");
5228
5229static PyObject *
5230posix_sched_getaffinity(PyObject *self, PyObject *args)
5231{
5232 pid_t pid;
5233 int ncpus;
5234 Py_cpu_set *res;
5235
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005236 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005237 &pid, &ncpus))
5238 return NULL;
5239 res = make_new_cpu_set(&cpu_set_type, ncpus);
5240 if (!res)
5241 return NULL;
5242 if (sched_getaffinity(pid, res->size, res->set)) {
5243 Py_DECREF(res);
5244 return posix_error();
5245 }
5246 return (PyObject *)res;
5247}
5248
Benjamin Peterson2740af82011-08-02 17:41:34 -05005249#endif /* HAVE_SCHED_SETAFFINITY */
5250
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005251#endif /* HAVE_SCHED_H */
5252
Neal Norwitzb59798b2003-03-21 01:43:31 +00005253/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005254/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5255#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005256#define DEV_PTY_FILE "/dev/ptc"
5257#define HAVE_DEV_PTMX
5258#else
5259#define DEV_PTY_FILE "/dev/ptmx"
5260#endif
5261
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005262#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005263#ifdef HAVE_PTY_H
5264#include <pty.h>
5265#else
5266#ifdef HAVE_LIBUTIL_H
5267#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005268#else
5269#ifdef HAVE_UTIL_H
5270#include <util.h>
5271#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005272#endif /* HAVE_LIBUTIL_H */
5273#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005274#ifdef HAVE_STROPTS_H
5275#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005276#endif
5277#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005278
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005279#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005280PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005281"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005282Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005283
5284static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005285posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005286{
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005288#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005289 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005290#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005291#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005293#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005295#endif
5296#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005297
Thomas Wouters70c21a12000-07-14 14:28:33 +00005298#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5300 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005301#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5303 if (slave_name == NULL)
5304 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005305
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 slave_fd = open(slave_name, O_RDWR);
5307 if (slave_fd < 0)
5308 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005309#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5311 if (master_fd < 0)
5312 return posix_error();
5313 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5314 /* change permission of slave */
5315 if (grantpt(master_fd) < 0) {
5316 PyOS_setsig(SIGCHLD, sig_saved);
5317 return posix_error();
5318 }
5319 /* unlock slave */
5320 if (unlockpt(master_fd) < 0) {
5321 PyOS_setsig(SIGCHLD, sig_saved);
5322 return posix_error();
5323 }
5324 PyOS_setsig(SIGCHLD, sig_saved);
5325 slave_name = ptsname(master_fd); /* get name of slave */
5326 if (slave_name == NULL)
5327 return posix_error();
5328 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5329 if (slave_fd < 0)
5330 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005331#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005332 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5333 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005334#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005335 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005336#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005337#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005338#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005339
Victor Stinner8c62be82010-05-06 00:08:46 +00005340 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005341
Fred Drake8cef4cf2000-06-28 16:40:38 +00005342}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005343#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005344
5345#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005346PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005347"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005348Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5349Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005350To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005351
5352static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005353posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005354{
Victor Stinner8c62be82010-05-06 00:08:46 +00005355 int master_fd = -1, result = 0;
5356 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005357
Victor Stinner8c62be82010-05-06 00:08:46 +00005358 _PyImport_AcquireLock();
5359 pid = forkpty(&master_fd, NULL, NULL, NULL);
5360 if (pid == 0) {
5361 /* child: this clobbers and resets the import lock. */
5362 PyOS_AfterFork();
5363 } else {
5364 /* parent: release the import lock. */
5365 result = _PyImport_ReleaseLock();
5366 }
5367 if (pid == -1)
5368 return posix_error();
5369 if (result < 0) {
5370 /* Don't clobber the OSError if the fork failed. */
5371 PyErr_SetString(PyExc_RuntimeError,
5372 "not holding the import lock");
5373 return NULL;
5374 }
5375 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005376}
5377#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005378
Ross Lagerwall7807c352011-03-17 20:20:30 +02005379
Guido van Rossumad0ee831995-03-01 10:34:45 +00005380#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005381PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005382"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005383Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005384
Barry Warsaw53699e91996-12-10 23:23:01 +00005385static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005386posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005387{
Victor Stinner8c62be82010-05-06 00:08:46 +00005388 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005389}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005390#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005392
Guido van Rossumad0ee831995-03-01 10:34:45 +00005393#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005394PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005395"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005396Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005397
Barry Warsaw53699e91996-12-10 23:23:01 +00005398static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005399posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005400{
Victor Stinner8c62be82010-05-06 00:08:46 +00005401 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005402}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005403#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005405
Guido van Rossumad0ee831995-03-01 10:34:45 +00005406#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005407PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005408"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005409Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005410
Barry Warsaw53699e91996-12-10 23:23:01 +00005411static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005412posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005413{
Victor Stinner8c62be82010-05-06 00:08:46 +00005414 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005415}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005416#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005418
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005419PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005420"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005422
Barry Warsaw53699e91996-12-10 23:23:01 +00005423static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005424posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005425{
Victor Stinner8c62be82010-05-06 00:08:46 +00005426 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005427}
5428
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005429#ifdef HAVE_GETGROUPLIST
5430PyDoc_STRVAR(posix_getgrouplist__doc__,
5431"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5432Returns a list of groups to which a user belongs.\n\n\
5433 user: username to lookup\n\
5434 group: base group id of the user");
5435
5436static PyObject *
5437posix_getgrouplist(PyObject *self, PyObject *args)
5438{
5439#ifdef NGROUPS_MAX
5440#define MAX_GROUPS NGROUPS_MAX
5441#else
5442 /* defined to be 16 on Solaris7, so this should be a small number */
5443#define MAX_GROUPS 64
5444#endif
5445
5446 const char *user;
5447 int i, ngroups;
5448 PyObject *list;
5449#ifdef __APPLE__
5450 int *groups, basegid;
5451#else
5452 gid_t *groups, basegid;
5453#endif
5454 ngroups = MAX_GROUPS;
5455
5456 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5457 return NULL;
5458
5459#ifdef __APPLE__
5460 groups = PyMem_Malloc(ngroups * sizeof(int));
5461#else
5462 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5463#endif
5464 if (groups == NULL)
5465 return PyErr_NoMemory();
5466
5467 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5468 PyMem_Del(groups);
5469 return posix_error();
5470 }
5471
5472 list = PyList_New(ngroups);
5473 if (list == NULL) {
5474 PyMem_Del(groups);
5475 return NULL;
5476 }
5477
5478 for (i = 0; i < ngroups; i++) {
5479 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5480 if (o == NULL) {
5481 Py_DECREF(list);
5482 PyMem_Del(groups);
5483 return NULL;
5484 }
5485 PyList_SET_ITEM(list, i, o);
5486 }
5487
5488 PyMem_Del(groups);
5489
5490 return list;
5491}
5492#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005493
Fred Drakec9680921999-12-13 16:37:25 +00005494#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005495PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005496"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005498
5499static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005500posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005501{
5502 PyObject *result = NULL;
5503
Fred Drakec9680921999-12-13 16:37:25 +00005504#ifdef NGROUPS_MAX
5505#define MAX_GROUPS NGROUPS_MAX
5506#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005507 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005508#define MAX_GROUPS 64
5509#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005510 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005511
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005512 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005513 * This is a helper variable to store the intermediate result when
5514 * that happens.
5515 *
5516 * To keep the code readable the OSX behaviour is unconditional,
5517 * according to the POSIX spec this should be safe on all unix-y
5518 * systems.
5519 */
5520 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005521 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005522
Victor Stinner8c62be82010-05-06 00:08:46 +00005523 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005524 if (n < 0) {
5525 if (errno == EINVAL) {
5526 n = getgroups(0, NULL);
5527 if (n == -1) {
5528 return posix_error();
5529 }
5530 if (n == 0) {
5531 /* Avoid malloc(0) */
5532 alt_grouplist = grouplist;
5533 } else {
5534 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5535 if (alt_grouplist == NULL) {
5536 errno = EINVAL;
5537 return posix_error();
5538 }
5539 n = getgroups(n, alt_grouplist);
5540 if (n == -1) {
5541 PyMem_Free(alt_grouplist);
5542 return posix_error();
5543 }
5544 }
5545 } else {
5546 return posix_error();
5547 }
5548 }
5549 result = PyList_New(n);
5550 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 int i;
5552 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005553 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005554 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005555 Py_DECREF(result);
5556 result = NULL;
5557 break;
Fred Drakec9680921999-12-13 16:37:25 +00005558 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005559 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005560 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005561 }
5562
5563 if (alt_grouplist != grouplist) {
5564 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005565 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005566
Fred Drakec9680921999-12-13 16:37:25 +00005567 return result;
5568}
5569#endif
5570
Antoine Pitroub7572f02009-12-02 20:46:48 +00005571#ifdef HAVE_INITGROUPS
5572PyDoc_STRVAR(posix_initgroups__doc__,
5573"initgroups(username, gid) -> None\n\n\
5574Call the system initgroups() to initialize the group access list with all of\n\
5575the groups of which the specified username is a member, plus the specified\n\
5576group id.");
5577
5578static PyObject *
5579posix_initgroups(PyObject *self, PyObject *args)
5580{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005581 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005583 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005584 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005585
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005586 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5587 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005588 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005589 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005590
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005591 res = initgroups(username, (gid_t) gid);
5592 Py_DECREF(oname);
5593 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005594 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005595
Victor Stinner8c62be82010-05-06 00:08:46 +00005596 Py_INCREF(Py_None);
5597 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005598}
5599#endif
5600
Martin v. Löwis606edc12002-06-13 21:09:11 +00005601#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005602PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005603"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005604Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005605
5606static PyObject *
5607posix_getpgid(PyObject *self, PyObject *args)
5608{
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 pid_t pid, pgid;
5610 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5611 return NULL;
5612 pgid = getpgid(pid);
5613 if (pgid < 0)
5614 return posix_error();
5615 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005616}
5617#endif /* HAVE_GETPGID */
5618
5619
Guido van Rossumb6775db1994-08-01 11:34:53 +00005620#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005621PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005622"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005623Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005624
Barry Warsaw53699e91996-12-10 23:23:01 +00005625static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005626posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005627{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005628#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005629 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005630#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005631 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005632#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005633}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005634#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005635
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005636
Guido van Rossumb6775db1994-08-01 11:34:53 +00005637#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005638PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005639"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005640Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005641
Barry Warsaw53699e91996-12-10 23:23:01 +00005642static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005643posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005644{
Guido van Rossum64933891994-10-20 21:56:42 +00005645#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005646 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005647#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005648 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005649#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005650 return posix_error();
5651 Py_INCREF(Py_None);
5652 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005653}
5654
Guido van Rossumb6775db1994-08-01 11:34:53 +00005655#endif /* HAVE_SETPGRP */
5656
Guido van Rossumad0ee831995-03-01 10:34:45 +00005657#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005658
5659#ifdef MS_WINDOWS
5660#include <tlhelp32.h>
5661
5662static PyObject*
5663win32_getppid()
5664{
5665 HANDLE snapshot;
5666 pid_t mypid;
5667 PyObject* result = NULL;
5668 BOOL have_record;
5669 PROCESSENTRY32 pe;
5670
5671 mypid = getpid(); /* This function never fails */
5672
5673 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5674 if (snapshot == INVALID_HANDLE_VALUE)
5675 return PyErr_SetFromWindowsErr(GetLastError());
5676
5677 pe.dwSize = sizeof(pe);
5678 have_record = Process32First(snapshot, &pe);
5679 while (have_record) {
5680 if (mypid == (pid_t)pe.th32ProcessID) {
5681 /* We could cache the ulong value in a static variable. */
5682 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5683 break;
5684 }
5685
5686 have_record = Process32Next(snapshot, &pe);
5687 }
5688
5689 /* If our loop exits and our pid was not found (result will be NULL)
5690 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5691 * error anyway, so let's raise it. */
5692 if (!result)
5693 result = PyErr_SetFromWindowsErr(GetLastError());
5694
5695 CloseHandle(snapshot);
5696
5697 return result;
5698}
5699#endif /*MS_WINDOWS*/
5700
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005701PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005702"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005703Return the parent's process id. If the parent process has already exited,\n\
5704Windows machines will still return its id; others systems will return the id\n\
5705of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005706
Barry Warsaw53699e91996-12-10 23:23:01 +00005707static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005708posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005709{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005710#ifdef MS_WINDOWS
5711 return win32_getppid();
5712#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005713 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005714#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005715}
5716#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005718
Fred Drake12c6e2d1999-12-14 21:25:03 +00005719#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005721"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005722Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005723
5724static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005725posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005726{
Victor Stinner8c62be82010-05-06 00:08:46 +00005727 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005728#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005729 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005730 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005731
5732 if (GetUserNameW(user_name, &num_chars)) {
5733 /* num_chars is the number of unicode chars plus null terminator */
5734 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005735 }
5736 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005737 result = PyErr_SetFromWindowsErr(GetLastError());
5738#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 char *name;
5740 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005741
Victor Stinner8c62be82010-05-06 00:08:46 +00005742 errno = 0;
5743 name = getlogin();
5744 if (name == NULL) {
5745 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005746 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005747 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005748 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 }
5750 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005751 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005752 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005753#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005754 return result;
5755}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005756#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005757
Guido van Rossumad0ee831995-03-01 10:34:45 +00005758#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005759PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005760"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005761Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005762
Barry Warsaw53699e91996-12-10 23:23:01 +00005763static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005764posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005765{
Victor Stinner8c62be82010-05-06 00:08:46 +00005766 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005767}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005768#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005770
Guido van Rossumad0ee831995-03-01 10:34:45 +00005771#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005773"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005774Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005775
Barry Warsaw53699e91996-12-10 23:23:01 +00005776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005777posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005778{
Victor Stinner8c62be82010-05-06 00:08:46 +00005779 pid_t pid;
5780 int sig;
5781 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5782 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005783#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005784 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5785 APIRET rc;
5786 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005787 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005788
5789 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5790 APIRET rc;
5791 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005792 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005793
5794 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005795 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005796#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005797 if (kill(pid, sig) == -1)
5798 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005799#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 Py_INCREF(Py_None);
5801 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005802}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005803#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005804
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005805#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005806PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005807"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005808Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005809
5810static PyObject *
5811posix_killpg(PyObject *self, PyObject *args)
5812{
Victor Stinner8c62be82010-05-06 00:08:46 +00005813 int sig;
5814 pid_t pgid;
5815 /* XXX some man pages make the `pgid` parameter an int, others
5816 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5817 take the same type. Moreover, pid_t is always at least as wide as
5818 int (else compilation of this module fails), which is safe. */
5819 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5820 return NULL;
5821 if (killpg(pgid, sig) == -1)
5822 return posix_error();
5823 Py_INCREF(Py_None);
5824 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005825}
5826#endif
5827
Brian Curtineb24d742010-04-12 17:16:38 +00005828#ifdef MS_WINDOWS
5829PyDoc_STRVAR(win32_kill__doc__,
5830"kill(pid, sig)\n\n\
5831Kill a process with a signal.");
5832
5833static PyObject *
5834win32_kill(PyObject *self, PyObject *args)
5835{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005836 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005837 DWORD pid, sig, err;
5838 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005839
Victor Stinner8c62be82010-05-06 00:08:46 +00005840 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5841 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005842
Victor Stinner8c62be82010-05-06 00:08:46 +00005843 /* Console processes which share a common console can be sent CTRL+C or
5844 CTRL+BREAK events, provided they handle said events. */
5845 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5846 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5847 err = GetLastError();
5848 PyErr_SetFromWindowsErr(err);
5849 }
5850 else
5851 Py_RETURN_NONE;
5852 }
Brian Curtineb24d742010-04-12 17:16:38 +00005853
Victor Stinner8c62be82010-05-06 00:08:46 +00005854 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5855 attempt to open and terminate the process. */
5856 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5857 if (handle == NULL) {
5858 err = GetLastError();
5859 return PyErr_SetFromWindowsErr(err);
5860 }
Brian Curtineb24d742010-04-12 17:16:38 +00005861
Victor Stinner8c62be82010-05-06 00:08:46 +00005862 if (TerminateProcess(handle, sig) == 0) {
5863 err = GetLastError();
5864 result = PyErr_SetFromWindowsErr(err);
5865 } else {
5866 Py_INCREF(Py_None);
5867 result = Py_None;
5868 }
Brian Curtineb24d742010-04-12 17:16:38 +00005869
Victor Stinner8c62be82010-05-06 00:08:46 +00005870 CloseHandle(handle);
5871 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005872}
5873#endif /* MS_WINDOWS */
5874
Guido van Rossumc0125471996-06-28 18:55:32 +00005875#ifdef HAVE_PLOCK
5876
5877#ifdef HAVE_SYS_LOCK_H
5878#include <sys/lock.h>
5879#endif
5880
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005881PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005882"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005883Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005884
Barry Warsaw53699e91996-12-10 23:23:01 +00005885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005886posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005887{
Victor Stinner8c62be82010-05-06 00:08:46 +00005888 int op;
5889 if (!PyArg_ParseTuple(args, "i:plock", &op))
5890 return NULL;
5891 if (plock(op) == -1)
5892 return posix_error();
5893 Py_INCREF(Py_None);
5894 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005895}
5896#endif
5897
Guido van Rossumb6775db1994-08-01 11:34:53 +00005898#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005899PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005900"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005901Set the current process's user id.");
5902
Barry Warsaw53699e91996-12-10 23:23:01 +00005903static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005904posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005905{
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 long uid_arg;
5907 uid_t uid;
5908 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5909 return NULL;
5910 uid = uid_arg;
5911 if (uid != uid_arg) {
5912 PyErr_SetString(PyExc_OverflowError, "user id too big");
5913 return NULL;
5914 }
5915 if (setuid(uid) < 0)
5916 return posix_error();
5917 Py_INCREF(Py_None);
5918 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005919}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005920#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005921
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005922
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005923#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005924PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005925"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005926Set the current process's effective user id.");
5927
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005928static PyObject *
5929posix_seteuid (PyObject *self, PyObject *args)
5930{
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 long euid_arg;
5932 uid_t euid;
5933 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5934 return NULL;
5935 euid = euid_arg;
5936 if (euid != euid_arg) {
5937 PyErr_SetString(PyExc_OverflowError, "user id too big");
5938 return NULL;
5939 }
5940 if (seteuid(euid) < 0) {
5941 return posix_error();
5942 } else {
5943 Py_INCREF(Py_None);
5944 return Py_None;
5945 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005946}
5947#endif /* HAVE_SETEUID */
5948
5949#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005950PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005951"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005952Set the current process's effective group id.");
5953
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005954static PyObject *
5955posix_setegid (PyObject *self, PyObject *args)
5956{
Victor Stinner8c62be82010-05-06 00:08:46 +00005957 long egid_arg;
5958 gid_t egid;
5959 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5960 return NULL;
5961 egid = egid_arg;
5962 if (egid != egid_arg) {
5963 PyErr_SetString(PyExc_OverflowError, "group id too big");
5964 return NULL;
5965 }
5966 if (setegid(egid) < 0) {
5967 return posix_error();
5968 } else {
5969 Py_INCREF(Py_None);
5970 return Py_None;
5971 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005972}
5973#endif /* HAVE_SETEGID */
5974
5975#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005976PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005977"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005978Set the current process's real and effective user ids.");
5979
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005980static PyObject *
5981posix_setreuid (PyObject *self, PyObject *args)
5982{
Victor Stinner8c62be82010-05-06 00:08:46 +00005983 long ruid_arg, euid_arg;
5984 uid_t ruid, euid;
5985 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5986 return NULL;
5987 if (ruid_arg == -1)
5988 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5989 else
5990 ruid = ruid_arg; /* otherwise, assign from our long */
5991 if (euid_arg == -1)
5992 euid = (uid_t)-1;
5993 else
5994 euid = euid_arg;
5995 if ((euid_arg != -1 && euid != euid_arg) ||
5996 (ruid_arg != -1 && ruid != ruid_arg)) {
5997 PyErr_SetString(PyExc_OverflowError, "user id too big");
5998 return NULL;
5999 }
6000 if (setreuid(ruid, euid) < 0) {
6001 return posix_error();
6002 } else {
6003 Py_INCREF(Py_None);
6004 return Py_None;
6005 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006006}
6007#endif /* HAVE_SETREUID */
6008
6009#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006010PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006011"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006012Set the current process's real and effective group ids.");
6013
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006014static PyObject *
6015posix_setregid (PyObject *self, PyObject *args)
6016{
Victor Stinner8c62be82010-05-06 00:08:46 +00006017 long rgid_arg, egid_arg;
6018 gid_t rgid, egid;
6019 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6020 return NULL;
6021 if (rgid_arg == -1)
6022 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6023 else
6024 rgid = rgid_arg; /* otherwise, assign from our long */
6025 if (egid_arg == -1)
6026 egid = (gid_t)-1;
6027 else
6028 egid = egid_arg;
6029 if ((egid_arg != -1 && egid != egid_arg) ||
6030 (rgid_arg != -1 && rgid != rgid_arg)) {
6031 PyErr_SetString(PyExc_OverflowError, "group id too big");
6032 return NULL;
6033 }
6034 if (setregid(rgid, egid) < 0) {
6035 return posix_error();
6036 } else {
6037 Py_INCREF(Py_None);
6038 return Py_None;
6039 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006040}
6041#endif /* HAVE_SETREGID */
6042
Guido van Rossumb6775db1994-08-01 11:34:53 +00006043#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006044PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006045"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006046Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006047
Barry Warsaw53699e91996-12-10 23:23:01 +00006048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006049posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006050{
Victor Stinner8c62be82010-05-06 00:08:46 +00006051 long gid_arg;
6052 gid_t gid;
6053 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6054 return NULL;
6055 gid = gid_arg;
6056 if (gid != gid_arg) {
6057 PyErr_SetString(PyExc_OverflowError, "group id too big");
6058 return NULL;
6059 }
6060 if (setgid(gid) < 0)
6061 return posix_error();
6062 Py_INCREF(Py_None);
6063 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006064}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006065#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006066
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006067#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006068PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006069"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006070Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006071
6072static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006073posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006074{
Victor Stinner8c62be82010-05-06 00:08:46 +00006075 int i, len;
6076 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006077
Victor Stinner8c62be82010-05-06 00:08:46 +00006078 if (!PySequence_Check(groups)) {
6079 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6080 return NULL;
6081 }
6082 len = PySequence_Size(groups);
6083 if (len > MAX_GROUPS) {
6084 PyErr_SetString(PyExc_ValueError, "too many groups");
6085 return NULL;
6086 }
6087 for(i = 0; i < len; i++) {
6088 PyObject *elem;
6089 elem = PySequence_GetItem(groups, i);
6090 if (!elem)
6091 return NULL;
6092 if (!PyLong_Check(elem)) {
6093 PyErr_SetString(PyExc_TypeError,
6094 "groups must be integers");
6095 Py_DECREF(elem);
6096 return NULL;
6097 } else {
6098 unsigned long x = PyLong_AsUnsignedLong(elem);
6099 if (PyErr_Occurred()) {
6100 PyErr_SetString(PyExc_TypeError,
6101 "group id too big");
6102 Py_DECREF(elem);
6103 return NULL;
6104 }
6105 grouplist[i] = x;
6106 /* read back the value to see if it fitted in gid_t */
6107 if (grouplist[i] != x) {
6108 PyErr_SetString(PyExc_TypeError,
6109 "group id too big");
6110 Py_DECREF(elem);
6111 return NULL;
6112 }
6113 }
6114 Py_DECREF(elem);
6115 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006116
Victor Stinner8c62be82010-05-06 00:08:46 +00006117 if (setgroups(len, grouplist) < 0)
6118 return posix_error();
6119 Py_INCREF(Py_None);
6120 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006121}
6122#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006123
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006124#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6125static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00006126wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006127{
Victor Stinner8c62be82010-05-06 00:08:46 +00006128 PyObject *result;
6129 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006130 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006131
Victor Stinner8c62be82010-05-06 00:08:46 +00006132 if (pid == -1)
6133 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006134
Victor Stinner8c62be82010-05-06 00:08:46 +00006135 if (struct_rusage == NULL) {
6136 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6137 if (m == NULL)
6138 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006139 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006140 Py_DECREF(m);
6141 if (struct_rusage == NULL)
6142 return NULL;
6143 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006144
Victor Stinner8c62be82010-05-06 00:08:46 +00006145 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6146 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6147 if (!result)
6148 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006149
6150#ifndef doubletime
6151#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6152#endif
6153
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 PyStructSequence_SET_ITEM(result, 0,
6155 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6156 PyStructSequence_SET_ITEM(result, 1,
6157 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006158#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006159 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6160 SET_INT(result, 2, ru->ru_maxrss);
6161 SET_INT(result, 3, ru->ru_ixrss);
6162 SET_INT(result, 4, ru->ru_idrss);
6163 SET_INT(result, 5, ru->ru_isrss);
6164 SET_INT(result, 6, ru->ru_minflt);
6165 SET_INT(result, 7, ru->ru_majflt);
6166 SET_INT(result, 8, ru->ru_nswap);
6167 SET_INT(result, 9, ru->ru_inblock);
6168 SET_INT(result, 10, ru->ru_oublock);
6169 SET_INT(result, 11, ru->ru_msgsnd);
6170 SET_INT(result, 12, ru->ru_msgrcv);
6171 SET_INT(result, 13, ru->ru_nsignals);
6172 SET_INT(result, 14, ru->ru_nvcsw);
6173 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006174#undef SET_INT
6175
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 if (PyErr_Occurred()) {
6177 Py_DECREF(result);
6178 return NULL;
6179 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006180
Victor Stinner8c62be82010-05-06 00:08:46 +00006181 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006182}
6183#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6184
6185#ifdef HAVE_WAIT3
6186PyDoc_STRVAR(posix_wait3__doc__,
6187"wait3(options) -> (pid, status, rusage)\n\n\
6188Wait for completion of a child process.");
6189
6190static PyObject *
6191posix_wait3(PyObject *self, PyObject *args)
6192{
Victor Stinner8c62be82010-05-06 00:08:46 +00006193 pid_t pid;
6194 int options;
6195 struct rusage ru;
6196 WAIT_TYPE status;
6197 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006198
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6200 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006201
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 Py_BEGIN_ALLOW_THREADS
6203 pid = wait3(&status, options, &ru);
6204 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006205
Victor Stinner8c62be82010-05-06 00:08:46 +00006206 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006207}
6208#endif /* HAVE_WAIT3 */
6209
6210#ifdef HAVE_WAIT4
6211PyDoc_STRVAR(posix_wait4__doc__,
6212"wait4(pid, options) -> (pid, status, rusage)\n\n\
6213Wait for completion of a given child process.");
6214
6215static PyObject *
6216posix_wait4(PyObject *self, PyObject *args)
6217{
Victor Stinner8c62be82010-05-06 00:08:46 +00006218 pid_t pid;
6219 int options;
6220 struct rusage ru;
6221 WAIT_TYPE status;
6222 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006223
Victor Stinner8c62be82010-05-06 00:08:46 +00006224 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
6225 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006226
Victor Stinner8c62be82010-05-06 00:08:46 +00006227 Py_BEGIN_ALLOW_THREADS
6228 pid = wait4(pid, &status, options, &ru);
6229 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006230
Victor Stinner8c62be82010-05-06 00:08:46 +00006231 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006232}
6233#endif /* HAVE_WAIT4 */
6234
Ross Lagerwall7807c352011-03-17 20:20:30 +02006235#if defined(HAVE_WAITID) && !defined(__APPLE__)
6236PyDoc_STRVAR(posix_waitid__doc__,
6237"waitid(idtype, id, options) -> waitid_result\n\n\
6238Wait for the completion of one or more child processes.\n\n\
6239idtype can be P_PID, P_PGID or P_ALL.\n\
6240id specifies the pid to wait on.\n\
6241options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6242or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6243Returns either waitid_result or None if WNOHANG is specified and there are\n\
6244no children in a waitable state.");
6245
6246static PyObject *
6247posix_waitid(PyObject *self, PyObject *args)
6248{
6249 PyObject *result;
6250 idtype_t idtype;
6251 id_t id;
6252 int options, res;
6253 siginfo_t si;
6254 si.si_pid = 0;
6255 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6256 return NULL;
6257 Py_BEGIN_ALLOW_THREADS
6258 res = waitid(idtype, id, &si, options);
6259 Py_END_ALLOW_THREADS
6260 if (res == -1)
6261 return posix_error();
6262
6263 if (si.si_pid == 0)
6264 Py_RETURN_NONE;
6265
6266 result = PyStructSequence_New(&WaitidResultType);
6267 if (!result)
6268 return NULL;
6269
6270 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6271 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6272 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6273 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6274 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6275 if (PyErr_Occurred()) {
6276 Py_DECREF(result);
6277 return NULL;
6278 }
6279
6280 return result;
6281}
6282#endif
6283
Guido van Rossumb6775db1994-08-01 11:34:53 +00006284#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006285PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006286"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006287Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006288
Barry Warsaw53699e91996-12-10 23:23:01 +00006289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006290posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006291{
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 pid_t pid;
6293 int options;
6294 WAIT_TYPE status;
6295 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006296
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6298 return NULL;
6299 Py_BEGIN_ALLOW_THREADS
6300 pid = waitpid(pid, &status, options);
6301 Py_END_ALLOW_THREADS
6302 if (pid == -1)
6303 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006304
Victor Stinner8c62be82010-05-06 00:08:46 +00006305 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006306}
6307
Tim Petersab034fa2002-02-01 11:27:43 +00006308#elif defined(HAVE_CWAIT)
6309
6310/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006311PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006312"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006313"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006314
6315static PyObject *
6316posix_waitpid(PyObject *self, PyObject *args)
6317{
Victor Stinner8c62be82010-05-06 00:08:46 +00006318 Py_intptr_t pid;
6319 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006320
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6322 return NULL;
6323 Py_BEGIN_ALLOW_THREADS
6324 pid = _cwait(&status, pid, options);
6325 Py_END_ALLOW_THREADS
6326 if (pid == -1)
6327 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006328
Victor Stinner8c62be82010-05-06 00:08:46 +00006329 /* shift the status left a byte so this is more like the POSIX waitpid */
6330 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006331}
6332#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006333
Guido van Rossumad0ee831995-03-01 10:34:45 +00006334#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006335PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006336"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006337Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006338
Barry Warsaw53699e91996-12-10 23:23:01 +00006339static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006340posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006341{
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 pid_t pid;
6343 WAIT_TYPE status;
6344 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006345
Victor Stinner8c62be82010-05-06 00:08:46 +00006346 Py_BEGIN_ALLOW_THREADS
6347 pid = wait(&status);
6348 Py_END_ALLOW_THREADS
6349 if (pid == -1)
6350 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006351
Victor Stinner8c62be82010-05-06 00:08:46 +00006352 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006353}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006354#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006357PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006358"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006359Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006360
Barry Warsaw53699e91996-12-10 23:23:01 +00006361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006362posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006363{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006364#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006366#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006367#ifdef MS_WINDOWS
Brian Curtind25aef52011-06-13 15:16:04 -05006368 return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006369 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006370#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006372#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006373#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006374}
6375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006376
Guido van Rossumb6775db1994-08-01 11:34:53 +00006377#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006378PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006379"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006380Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006381
Barry Warsaw53699e91996-12-10 23:23:01 +00006382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006383posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006384{
Victor Stinner8c62be82010-05-06 00:08:46 +00006385 PyObject* v;
6386 char buf[MAXPATHLEN];
6387 PyObject *opath;
6388 char *path;
6389 int n;
6390 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006391
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 if (!PyArg_ParseTuple(args, "O&:readlink",
6393 PyUnicode_FSConverter, &opath))
6394 return NULL;
6395 path = PyBytes_AsString(opath);
6396 v = PySequence_GetItem(args, 0);
6397 if (v == NULL) {
6398 Py_DECREF(opath);
6399 return NULL;
6400 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006401
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 if (PyUnicode_Check(v)) {
6403 arg_is_unicode = 1;
6404 }
6405 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006406
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 Py_BEGIN_ALLOW_THREADS
6408 n = readlink(path, buf, (int) sizeof buf);
6409 Py_END_ALLOW_THREADS
6410 if (n < 0)
6411 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006412
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006414 if (arg_is_unicode)
6415 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6416 else
6417 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006418}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006419#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006420
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006421
Brian Curtin52173d42010-12-02 18:29:18 +00006422#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006423PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006424"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006425Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006426
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006428posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006429{
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006431}
6432#endif /* HAVE_SYMLINK */
6433
Brian Curtind40e6f72010-07-08 21:39:08 +00006434#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6435
6436PyDoc_STRVAR(win_readlink__doc__,
6437"readlink(path) -> path\n\n\
6438Return a string representing the path to which the symbolic link points.");
6439
Brian Curtind40e6f72010-07-08 21:39:08 +00006440/* Windows readlink implementation */
6441static PyObject *
6442win_readlink(PyObject *self, PyObject *args)
6443{
6444 wchar_t *path;
6445 DWORD n_bytes_returned;
6446 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006447 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00006448 HANDLE reparse_point_handle;
6449
6450 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6451 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6452 wchar_t *print_name;
6453
6454 if (!PyArg_ParseTuple(args,
Victor Stinnereb5657a2011-09-30 01:44:27 +02006455 "U:readlink",
6456 &po))
6457 return NULL;
6458 path = PyUnicode_AsUnicode(po);
6459 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006460 return NULL;
6461
6462 /* First get a handle to the reparse point */
6463 Py_BEGIN_ALLOW_THREADS
6464 reparse_point_handle = CreateFileW(
6465 path,
6466 0,
6467 0,
6468 0,
6469 OPEN_EXISTING,
6470 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6471 0);
6472 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006473
Brian Curtind40e6f72010-07-08 21:39:08 +00006474 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006475 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006476
Brian Curtind40e6f72010-07-08 21:39:08 +00006477 Py_BEGIN_ALLOW_THREADS
6478 /* New call DeviceIoControl to read the reparse point */
6479 io_result = DeviceIoControl(
6480 reparse_point_handle,
6481 FSCTL_GET_REPARSE_POINT,
6482 0, 0, /* in buffer */
6483 target_buffer, sizeof(target_buffer),
6484 &n_bytes_returned,
6485 0 /* we're not using OVERLAPPED_IO */
6486 );
6487 CloseHandle(reparse_point_handle);
6488 Py_END_ALLOW_THREADS
6489
6490 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006491 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006492
6493 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6494 {
6495 PyErr_SetString(PyExc_ValueError,
6496 "not a symbolic link");
6497 return NULL;
6498 }
Brian Curtin74e45612010-07-09 15:58:59 +00006499 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6500 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6501
6502 result = PyUnicode_FromWideChar(print_name,
6503 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006504 return result;
6505}
6506
6507#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6508
Brian Curtin52173d42010-12-02 18:29:18 +00006509#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006510
6511/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6512static int has_CreateSymbolicLinkW = 0;
6513static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6514static int
6515check_CreateSymbolicLinkW()
6516{
6517 HINSTANCE hKernel32;
6518 /* only recheck */
6519 if (has_CreateSymbolicLinkW)
6520 return has_CreateSymbolicLinkW;
6521 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006522 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6523 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006524 if (Py_CreateSymbolicLinkW)
6525 has_CreateSymbolicLinkW = 1;
6526 return has_CreateSymbolicLinkW;
6527}
6528
6529PyDoc_STRVAR(win_symlink__doc__,
6530"symlink(src, dst, target_is_directory=False)\n\n\
6531Create a symbolic link pointing to src named dst.\n\
6532target_is_directory is required if the target is to be interpreted as\n\
6533a directory.\n\
6534This function requires Windows 6.0 or greater, and raises a\n\
6535NotImplementedError otherwise.");
6536
6537static PyObject *
6538win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6539{
6540 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006541 PyObject *osrc, *odest;
6542 PyObject *usrc = NULL, *udest = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006543 wchar_t *wsrc, *wdest;
Brian Curtind40e6f72010-07-08 21:39:08 +00006544 int target_is_directory = 0;
6545 DWORD res;
6546 WIN32_FILE_ATTRIBUTE_DATA src_info;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006547
Brian Curtind40e6f72010-07-08 21:39:08 +00006548 if (!check_CreateSymbolicLinkW())
6549 {
6550 /* raise NotImplementedError */
6551 return PyErr_Format(PyExc_NotImplementedError,
6552 "CreateSymbolicLinkW not found");
6553 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006554 if (!PyArg_ParseTupleAndKeywords(
6555 args, kwargs, "OO|i:symlink", kwlist,
6556 &osrc, &odest, &target_is_directory))
Brian Curtind40e6f72010-07-08 21:39:08 +00006557 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006558
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006559 usrc = win32_decode_filename(osrc);
6560 if (!usrc)
6561 return NULL;
6562 udest = win32_decode_filename(odest);
6563 if (!udest)
6564 goto error;
6565
Brian Curtin3b4499c2010-12-28 14:31:47 +00006566 if (win32_can_symlink == 0)
6567 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6568
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006569 wsrc = PyUnicode_AsUnicode(usrc);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006570 if (wsrc == NULL)
6571 goto error;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006572 wdest = PyUnicode_AsUnicode(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006573 if (wsrc == NULL)
6574 goto error;
6575
Brian Curtind40e6f72010-07-08 21:39:08 +00006576 /* if src is a directory, ensure target_is_directory==1 */
6577 if(
6578 GetFileAttributesExW(
Victor Stinnereb5657a2011-09-30 01:44:27 +02006579 wsrc, GetFileExInfoStandard, &src_info
Brian Curtind40e6f72010-07-08 21:39:08 +00006580 ))
6581 {
6582 target_is_directory = target_is_directory ||
6583 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
6584 }
6585
6586 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006587 res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Brian Curtind40e6f72010-07-08 21:39:08 +00006588 Py_END_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006589
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006590 Py_DECREF(usrc);
6591 Py_DECREF(udest);
Brian Curtind40e6f72010-07-08 21:39:08 +00006592 if (!res)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006593 return win32_error_object("symlink", osrc);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006594
Brian Curtind40e6f72010-07-08 21:39:08 +00006595 Py_INCREF(Py_None);
6596 return Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006597
6598error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006599 Py_XDECREF(usrc);
6600 Py_XDECREF(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006601 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006602}
Brian Curtin52173d42010-12-02 18:29:18 +00006603#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006604
6605#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006606#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6607static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006608system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006609{
6610 ULONG value = 0;
6611
6612 Py_BEGIN_ALLOW_THREADS
6613 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6614 Py_END_ALLOW_THREADS
6615
6616 return value;
6617}
6618
6619static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006620posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006621{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006622 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 return Py_BuildValue("ddddd",
6624 (double)0 /* t.tms_utime / HZ */,
6625 (double)0 /* t.tms_stime / HZ */,
6626 (double)0 /* t.tms_cutime / HZ */,
6627 (double)0 /* t.tms_cstime / HZ */,
6628 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006629}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006630#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006631#define NEED_TICKS_PER_SECOND
6632static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006633static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006634posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006635{
Victor Stinner8c62be82010-05-06 00:08:46 +00006636 struct tms t;
6637 clock_t c;
6638 errno = 0;
6639 c = times(&t);
6640 if (c == (clock_t) -1)
6641 return posix_error();
6642 return Py_BuildValue("ddddd",
6643 (double)t.tms_utime / ticks_per_second,
6644 (double)t.tms_stime / ticks_per_second,
6645 (double)t.tms_cutime / ticks_per_second,
6646 (double)t.tms_cstime / ticks_per_second,
6647 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006648}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006649#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006650#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006651
6652
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006653#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006654#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006655static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006656posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006657{
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 FILETIME create, exit, kernel, user;
6659 HANDLE hProc;
6660 hProc = GetCurrentProcess();
6661 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6662 /* The fields of a FILETIME structure are the hi and lo part
6663 of a 64-bit value expressed in 100 nanosecond units.
6664 1e7 is one second in such units; 1e-7 the inverse.
6665 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6666 */
6667 return Py_BuildValue(
6668 "ddddd",
6669 (double)(user.dwHighDateTime*429.4967296 +
6670 user.dwLowDateTime*1e-7),
6671 (double)(kernel.dwHighDateTime*429.4967296 +
6672 kernel.dwLowDateTime*1e-7),
6673 (double)0,
6674 (double)0,
6675 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006676}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006677#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006678
6679#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006680PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006681"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006682Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006683#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006684
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006685
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006686#ifdef HAVE_GETSID
6687PyDoc_STRVAR(posix_getsid__doc__,
6688"getsid(pid) -> sid\n\n\
6689Call the system call getsid().");
6690
6691static PyObject *
6692posix_getsid(PyObject *self, PyObject *args)
6693{
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 pid_t pid;
6695 int sid;
6696 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6697 return NULL;
6698 sid = getsid(pid);
6699 if (sid < 0)
6700 return posix_error();
6701 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006702}
6703#endif /* HAVE_GETSID */
6704
6705
Guido van Rossumb6775db1994-08-01 11:34:53 +00006706#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006708"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006710
Barry Warsaw53699e91996-12-10 23:23:01 +00006711static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006712posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006713{
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 if (setsid() < 0)
6715 return posix_error();
6716 Py_INCREF(Py_None);
6717 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006718}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006719#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006720
Guido van Rossumb6775db1994-08-01 11:34:53 +00006721#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006722PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006723"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006724Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006725
Barry Warsaw53699e91996-12-10 23:23:01 +00006726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006727posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006728{
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 pid_t pid;
6730 int pgrp;
6731 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6732 return NULL;
6733 if (setpgid(pid, pgrp) < 0)
6734 return posix_error();
6735 Py_INCREF(Py_None);
6736 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006737}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006738#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006739
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006740
Guido van Rossumb6775db1994-08-01 11:34:53 +00006741#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006742PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006743"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006744Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006745
Barry Warsaw53699e91996-12-10 23:23:01 +00006746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006747posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006748{
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 int fd;
6750 pid_t pgid;
6751 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6752 return NULL;
6753 pgid = tcgetpgrp(fd);
6754 if (pgid < 0)
6755 return posix_error();
6756 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006757}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006758#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006760
Guido van Rossumb6775db1994-08-01 11:34:53 +00006761#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006762PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006763"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006764Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006765
Barry Warsaw53699e91996-12-10 23:23:01 +00006766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006767posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006768{
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 int fd;
6770 pid_t pgid;
6771 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6772 return NULL;
6773 if (tcsetpgrp(fd, pgid) < 0)
6774 return posix_error();
6775 Py_INCREF(Py_None);
6776 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006777}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006778#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006779
Guido van Rossum687dd131993-05-17 08:34:16 +00006780/* Functions acting on file descriptors */
6781
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006782PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006783"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006784Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006785
Barry Warsaw53699e91996-12-10 23:23:01 +00006786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006787posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006788{
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 PyObject *ofile;
6790 char *file;
6791 int flag;
6792 int mode = 0777;
6793 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006794
6795#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006796 PyObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006797 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02006798 wchar_t *wpath = PyUnicode_AsUnicode(po);
6799 if (wpath == NULL)
6800 return NULL;
6801
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006803 fd = _wopen(wpath, flag, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 Py_END_ALLOW_THREADS
6805 if (fd < 0)
6806 return posix_error();
6807 return PyLong_FromLong((long)fd);
6808 }
6809 /* Drop the argument parsing error as narrow strings
6810 are also valid. */
6811 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006812#endif
6813
Victor Stinner26de69d2011-06-17 15:15:38 +02006814 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 PyUnicode_FSConverter, &ofile,
6816 &flag, &mode))
6817 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006818#ifdef MS_WINDOWS
6819 if (win32_warn_bytes_api()) {
6820 Py_DECREF(ofile);
6821 return NULL;
6822 }
6823#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 file = PyBytes_AsString(ofile);
6825 Py_BEGIN_ALLOW_THREADS
6826 fd = open(file, flag, mode);
6827 Py_END_ALLOW_THREADS
6828 if (fd < 0)
6829 return posix_error_with_allocated_filename(ofile);
6830 Py_DECREF(ofile);
6831 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006832}
6833
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006834
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006835PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006836"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006837Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006838
Barry Warsaw53699e91996-12-10 23:23:01 +00006839static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006840posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006841{
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 int fd, res;
6843 if (!PyArg_ParseTuple(args, "i:close", &fd))
6844 return NULL;
6845 if (!_PyVerify_fd(fd))
6846 return posix_error();
6847 Py_BEGIN_ALLOW_THREADS
6848 res = close(fd);
6849 Py_END_ALLOW_THREADS
6850 if (res < 0)
6851 return posix_error();
6852 Py_INCREF(Py_None);
6853 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006854}
6855
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006856
Victor Stinner8c62be82010-05-06 00:08:46 +00006857PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006858"closerange(fd_low, fd_high)\n\n\
6859Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6860
6861static PyObject *
6862posix_closerange(PyObject *self, PyObject *args)
6863{
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 int fd_from, fd_to, i;
6865 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6866 return NULL;
6867 Py_BEGIN_ALLOW_THREADS
6868 for (i = fd_from; i < fd_to; i++)
6869 if (_PyVerify_fd(i))
6870 close(i);
6871 Py_END_ALLOW_THREADS
6872 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006873}
6874
6875
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006876PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006877"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006878Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006879
Barry Warsaw53699e91996-12-10 23:23:01 +00006880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006881posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006882{
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 int fd;
6884 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6885 return NULL;
6886 if (!_PyVerify_fd(fd))
6887 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 if (fd < 0)
6890 return posix_error();
6891 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006892}
6893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006895PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006896"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006897Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006898
Barry Warsaw53699e91996-12-10 23:23:01 +00006899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006900posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006901{
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 int fd, fd2, res;
6903 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6904 return NULL;
6905 if (!_PyVerify_fd_dup2(fd, fd2))
6906 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 if (res < 0)
6909 return posix_error();
6910 Py_INCREF(Py_None);
6911 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006912}
6913
Ross Lagerwall7807c352011-03-17 20:20:30 +02006914#ifdef HAVE_LOCKF
6915PyDoc_STRVAR(posix_lockf__doc__,
6916"lockf(fd, cmd, len)\n\n\
6917Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6918fd is an open file descriptor.\n\
6919cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6920F_TEST.\n\
6921len specifies the section of the file to lock.");
6922
6923static PyObject *
6924posix_lockf(PyObject *self, PyObject *args)
6925{
6926 int fd, cmd, res;
6927 off_t len;
6928 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6929 &fd, &cmd, _parse_off_t, &len))
6930 return NULL;
6931
6932 Py_BEGIN_ALLOW_THREADS
6933 res = lockf(fd, cmd, len);
6934 Py_END_ALLOW_THREADS
6935
6936 if (res < 0)
6937 return posix_error();
6938
6939 Py_RETURN_NONE;
6940}
6941#endif
6942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006944PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006945"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006946Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006947
Barry Warsaw53699e91996-12-10 23:23:01 +00006948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006949posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006950{
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006952#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006954#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006956#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02006957 PyObject *posobj;
6958 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006960#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6962 switch (how) {
6963 case 0: how = SEEK_SET; break;
6964 case 1: how = SEEK_CUR; break;
6965 case 2: how = SEEK_END; break;
6966 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006967#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006968
Ross Lagerwall8e749672011-03-17 21:54:07 +02006969#if !defined(HAVE_LARGEFILE_SUPPORT)
6970 pos = PyLong_AsLong(posobj);
6971#else
6972 pos = PyLong_AsLongLong(posobj);
6973#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 if (PyErr_Occurred())
6975 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006976
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 if (!_PyVerify_fd(fd))
6978 return posix_error();
6979 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006980#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006981 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006982#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006984#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 Py_END_ALLOW_THREADS
6986 if (res < 0)
6987 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006988
6989#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006990 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006991#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006993#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006994}
6995
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006996
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006997PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006998"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006999Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007000
Barry Warsaw53699e91996-12-10 23:23:01 +00007001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007002posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007003{
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 int fd, size;
7005 Py_ssize_t n;
7006 PyObject *buffer;
7007 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7008 return NULL;
7009 if (size < 0) {
7010 errno = EINVAL;
7011 return posix_error();
7012 }
7013 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7014 if (buffer == NULL)
7015 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007016 if (!_PyVerify_fd(fd)) {
7017 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007019 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 Py_BEGIN_ALLOW_THREADS
7021 n = read(fd, PyBytes_AS_STRING(buffer), size);
7022 Py_END_ALLOW_THREADS
7023 if (n < 0) {
7024 Py_DECREF(buffer);
7025 return posix_error();
7026 }
7027 if (n != size)
7028 _PyBytes_Resize(&buffer, n);
7029 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007030}
7031
Ross Lagerwall7807c352011-03-17 20:20:30 +02007032#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7033 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007034static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007035iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7036{
7037 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007038 Py_ssize_t blen, total = 0;
7039
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007040 *iov = PyMem_New(struct iovec, cnt);
7041 if (*iov == NULL) {
7042 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007043 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007044 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007045
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007046 *buf = PyMem_New(Py_buffer, cnt);
7047 if (*buf == NULL) {
7048 PyMem_Del(*iov);
7049 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007050 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007051 }
7052
7053 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007054 PyObject *item = PySequence_GetItem(seq, i);
7055 if (item == NULL)
7056 goto fail;
7057 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7058 Py_DECREF(item);
7059 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007060 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007061 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007062 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007063 blen = (*buf)[i].len;
7064 (*iov)[i].iov_len = blen;
7065 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007066 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007067 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007068
7069fail:
7070 PyMem_Del(*iov);
7071 for (j = 0; j < i; j++) {
7072 PyBuffer_Release(&(*buf)[j]);
7073 }
7074 PyMem_Del(*buf);
7075 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007076}
7077
7078static void
7079iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7080{
7081 int i;
7082 PyMem_Del(iov);
7083 for (i = 0; i < cnt; i++) {
7084 PyBuffer_Release(&buf[i]);
7085 }
7086 PyMem_Del(buf);
7087}
7088#endif
7089
Ross Lagerwall7807c352011-03-17 20:20:30 +02007090#ifdef HAVE_READV
7091PyDoc_STRVAR(posix_readv__doc__,
7092"readv(fd, buffers) -> bytesread\n\n\
7093Read from a file descriptor into a number of writable buffers. buffers\n\
7094is an arbitrary sequence of writable buffers.\n\
7095Returns the total number of bytes read.");
7096
7097static PyObject *
7098posix_readv(PyObject *self, PyObject *args)
7099{
7100 int fd, cnt;
7101 Py_ssize_t n;
7102 PyObject *seq;
7103 struct iovec *iov;
7104 Py_buffer *buf;
7105
7106 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7107 return NULL;
7108 if (!PySequence_Check(seq)) {
7109 PyErr_SetString(PyExc_TypeError,
7110 "readv() arg 2 must be a sequence");
7111 return NULL;
7112 }
7113 cnt = PySequence_Size(seq);
7114
7115 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7116 return NULL;
7117
7118 Py_BEGIN_ALLOW_THREADS
7119 n = readv(fd, iov, cnt);
7120 Py_END_ALLOW_THREADS
7121
7122 iov_cleanup(iov, buf, cnt);
7123 return PyLong_FromSsize_t(n);
7124}
7125#endif
7126
7127#ifdef HAVE_PREAD
7128PyDoc_STRVAR(posix_pread__doc__,
7129"pread(fd, buffersize, offset) -> string\n\n\
7130Read from a file descriptor, fd, at a position of offset. It will read up\n\
7131to buffersize number of bytes. The file offset remains unchanged.");
7132
7133static PyObject *
7134posix_pread(PyObject *self, PyObject *args)
7135{
7136 int fd, size;
7137 off_t offset;
7138 Py_ssize_t n;
7139 PyObject *buffer;
7140 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7141 return NULL;
7142
7143 if (size < 0) {
7144 errno = EINVAL;
7145 return posix_error();
7146 }
7147 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7148 if (buffer == NULL)
7149 return NULL;
7150 if (!_PyVerify_fd(fd)) {
7151 Py_DECREF(buffer);
7152 return posix_error();
7153 }
7154 Py_BEGIN_ALLOW_THREADS
7155 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7156 Py_END_ALLOW_THREADS
7157 if (n < 0) {
7158 Py_DECREF(buffer);
7159 return posix_error();
7160 }
7161 if (n != size)
7162 _PyBytes_Resize(&buffer, n);
7163 return buffer;
7164}
7165#endif
7166
7167PyDoc_STRVAR(posix_write__doc__,
7168"write(fd, string) -> byteswritten\n\n\
7169Write a string to a file descriptor.");
7170
7171static PyObject *
7172posix_write(PyObject *self, PyObject *args)
7173{
7174 Py_buffer pbuf;
7175 int fd;
7176 Py_ssize_t size, len;
7177
7178 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7179 return NULL;
7180 if (!_PyVerify_fd(fd)) {
7181 PyBuffer_Release(&pbuf);
7182 return posix_error();
7183 }
7184 len = pbuf.len;
7185 Py_BEGIN_ALLOW_THREADS
7186#if defined(MS_WIN64) || defined(MS_WINDOWS)
7187 if (len > INT_MAX)
7188 len = INT_MAX;
7189 size = write(fd, pbuf.buf, (int)len);
7190#else
7191 size = write(fd, pbuf.buf, len);
7192#endif
7193 Py_END_ALLOW_THREADS
7194 PyBuffer_Release(&pbuf);
7195 if (size < 0)
7196 return posix_error();
7197 return PyLong_FromSsize_t(size);
7198}
7199
7200#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007201PyDoc_STRVAR(posix_sendfile__doc__,
7202"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7203sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7204 -> byteswritten\n\
7205Copy nbytes bytes from file descriptor in to file descriptor out.");
7206
7207static PyObject *
7208posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7209{
7210 int in, out;
7211 Py_ssize_t ret;
7212 off_t offset;
7213
7214#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7215#ifndef __APPLE__
7216 Py_ssize_t len;
7217#endif
7218 PyObject *headers = NULL, *trailers = NULL;
7219 Py_buffer *hbuf, *tbuf;
7220 off_t sbytes;
7221 struct sf_hdtr sf;
7222 int flags = 0;
7223 sf.headers = NULL;
7224 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007225 static char *keywords[] = {"out", "in",
7226 "offset", "count",
7227 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007228
7229#ifdef __APPLE__
7230 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007231 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007232#else
7233 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007234 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007235#endif
7236 &headers, &trailers, &flags))
7237 return NULL;
7238 if (headers != NULL) {
7239 if (!PySequence_Check(headers)) {
7240 PyErr_SetString(PyExc_TypeError,
7241 "sendfile() headers must be a sequence or None");
7242 return NULL;
7243 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007244 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007245 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007246 if (sf.hdr_cnt > 0 &&
7247 !(i = iov_setup(&(sf.headers), &hbuf,
7248 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007249 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007250#ifdef __APPLE__
7251 sbytes += i;
7252#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007253 }
7254 }
7255 if (trailers != NULL) {
7256 if (!PySequence_Check(trailers)) {
7257 PyErr_SetString(PyExc_TypeError,
7258 "sendfile() trailers must be a sequence or None");
7259 return NULL;
7260 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007261 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007262 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007263 if (sf.trl_cnt > 0 &&
7264 !(i = iov_setup(&(sf.trailers), &tbuf,
7265 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007266 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007267#ifdef __APPLE__
7268 sbytes += i;
7269#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007270 }
7271 }
7272
7273 Py_BEGIN_ALLOW_THREADS
7274#ifdef __APPLE__
7275 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7276#else
7277 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7278#endif
7279 Py_END_ALLOW_THREADS
7280
7281 if (sf.headers != NULL)
7282 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7283 if (sf.trailers != NULL)
7284 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7285
7286 if (ret < 0) {
7287 if ((errno == EAGAIN) || (errno == EBUSY)) {
7288 if (sbytes != 0) {
7289 // some data has been sent
7290 goto done;
7291 }
7292 else {
7293 // no data has been sent; upper application is supposed
7294 // to retry on EAGAIN or EBUSY
7295 return posix_error();
7296 }
7297 }
7298 return posix_error();
7299 }
7300 goto done;
7301
7302done:
7303 #if !defined(HAVE_LARGEFILE_SUPPORT)
7304 return Py_BuildValue("l", sbytes);
7305 #else
7306 return Py_BuildValue("L", sbytes);
7307 #endif
7308
7309#else
7310 Py_ssize_t count;
7311 PyObject *offobj;
7312 static char *keywords[] = {"out", "in",
7313 "offset", "count", NULL};
7314 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7315 keywords, &out, &in, &offobj, &count))
7316 return NULL;
7317#ifdef linux
7318 if (offobj == Py_None) {
7319 Py_BEGIN_ALLOW_THREADS
7320 ret = sendfile(out, in, NULL, count);
7321 Py_END_ALLOW_THREADS
7322 if (ret < 0)
7323 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007324 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007325 }
7326#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007327 if (!_parse_off_t(offobj, &offset))
7328 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007329 Py_BEGIN_ALLOW_THREADS
7330 ret = sendfile(out, in, &offset, count);
7331 Py_END_ALLOW_THREADS
7332 if (ret < 0)
7333 return posix_error();
7334 return Py_BuildValue("n", ret);
7335#endif
7336}
7337#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007338
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007339PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007340"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007341Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007342
Barry Warsaw53699e91996-12-10 23:23:01 +00007343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007344posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007345{
Victor Stinner8c62be82010-05-06 00:08:46 +00007346 int fd;
7347 STRUCT_STAT st;
7348 int res;
7349 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
7350 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007351#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007352 /* on OpenVMS we must ensure that all bytes are written to the file */
7353 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007354#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007355 if (!_PyVerify_fd(fd))
7356 return posix_error();
7357 Py_BEGIN_ALLOW_THREADS
7358 res = FSTAT(fd, &st);
7359 Py_END_ALLOW_THREADS
7360 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007361#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007362 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007363#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007364 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007365#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007366 }
Tim Peters5aa91602002-01-30 05:46:57 +00007367
Victor Stinner8c62be82010-05-06 00:08:46 +00007368 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00007369}
7370
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007371PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007372"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007373Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007374connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007375
7376static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007377posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007378{
Victor Stinner8c62be82010-05-06 00:08:46 +00007379 int fd;
7380 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7381 return NULL;
7382 if (!_PyVerify_fd(fd))
7383 return PyBool_FromLong(0);
7384 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007385}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007386
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007387#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007388PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007389"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007390Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007391
Barry Warsaw53699e91996-12-10 23:23:01 +00007392static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007393posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007394{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007395#if defined(PYOS_OS2)
7396 HFILE read, write;
7397 APIRET rc;
7398
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007399 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007400 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007401 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007402
7403 return Py_BuildValue("(ii)", read, write);
7404#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007405#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007406 int fds[2];
7407 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007408 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007409 if (res != 0)
7410 return posix_error();
7411 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007412#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007413 HANDLE read, write;
7414 int read_fd, write_fd;
7415 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007416 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007417 if (!ok)
7418 return win32_error("CreatePipe", NULL);
7419 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7420 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7421 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007422#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007423#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007424}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007425#endif /* HAVE_PIPE */
7426
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007427#ifdef HAVE_PIPE2
7428PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007429"pipe2(flags) -> (read_end, write_end)\n\n\
7430Create a pipe with flags set atomically.\n\
7431flags can be constructed by ORing together one or more of these values:\n\
7432O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007433");
7434
7435static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007436posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007437{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007438 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007439 int fds[2];
7440 int res;
7441
Charles-François Natali368f34b2011-06-06 19:49:47 +02007442 flags = PyLong_AsLong(arg);
7443 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007444 return NULL;
7445
7446 res = pipe2(fds, flags);
7447 if (res != 0)
7448 return posix_error();
7449 return Py_BuildValue("(ii)", fds[0], fds[1]);
7450}
7451#endif /* HAVE_PIPE2 */
7452
Ross Lagerwall7807c352011-03-17 20:20:30 +02007453#ifdef HAVE_WRITEV
7454PyDoc_STRVAR(posix_writev__doc__,
7455"writev(fd, buffers) -> byteswritten\n\n\
7456Write the contents of buffers to a file descriptor, where buffers is an\n\
7457arbitrary sequence of buffers.\n\
7458Returns the total bytes written.");
7459
7460static PyObject *
7461posix_writev(PyObject *self, PyObject *args)
7462{
7463 int fd, cnt;
7464 Py_ssize_t res;
7465 PyObject *seq;
7466 struct iovec *iov;
7467 Py_buffer *buf;
7468 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7469 return NULL;
7470 if (!PySequence_Check(seq)) {
7471 PyErr_SetString(PyExc_TypeError,
7472 "writev() arg 2 must be a sequence");
7473 return NULL;
7474 }
7475 cnt = PySequence_Size(seq);
7476
7477 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7478 return NULL;
7479 }
7480
7481 Py_BEGIN_ALLOW_THREADS
7482 res = writev(fd, iov, cnt);
7483 Py_END_ALLOW_THREADS
7484
7485 iov_cleanup(iov, buf, cnt);
7486 return PyLong_FromSsize_t(res);
7487}
7488#endif
7489
7490#ifdef HAVE_PWRITE
7491PyDoc_STRVAR(posix_pwrite__doc__,
7492"pwrite(fd, string, offset) -> byteswritten\n\n\
7493Write string to a file descriptor, fd, from offset, leaving the file\n\
7494offset unchanged.");
7495
7496static PyObject *
7497posix_pwrite(PyObject *self, PyObject *args)
7498{
7499 Py_buffer pbuf;
7500 int fd;
7501 off_t offset;
7502 Py_ssize_t size;
7503
7504 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7505 return NULL;
7506
7507 if (!_PyVerify_fd(fd)) {
7508 PyBuffer_Release(&pbuf);
7509 return posix_error();
7510 }
7511 Py_BEGIN_ALLOW_THREADS
7512 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7513 Py_END_ALLOW_THREADS
7514 PyBuffer_Release(&pbuf);
7515 if (size < 0)
7516 return posix_error();
7517 return PyLong_FromSsize_t(size);
7518}
7519#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007520
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007521#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007522PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007523"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007524Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007525
Barry Warsaw53699e91996-12-10 23:23:01 +00007526static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007527posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007528{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007529 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 char *filename;
7531 int mode = 0666;
7532 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007533 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7534 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007536 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007537 Py_BEGIN_ALLOW_THREADS
7538 res = mkfifo(filename, mode);
7539 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007540 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007541 if (res < 0)
7542 return posix_error();
7543 Py_INCREF(Py_None);
7544 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007545}
7546#endif
7547
7548
Neal Norwitz11690112002-07-30 01:08:28 +00007549#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007550PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007551"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007552Create a filesystem node (file, device special file or named pipe)\n\
7553named filename. mode specifies both the permissions to use and the\n\
7554type of node to be created, being combined (bitwise OR) with one of\n\
7555S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007556device defines the newly created device special file (probably using\n\
7557os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007558
7559
7560static PyObject *
7561posix_mknod(PyObject *self, PyObject *args)
7562{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007563 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007564 char *filename;
7565 int mode = 0600;
7566 int device = 0;
7567 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007568 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7569 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007570 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007571 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 Py_BEGIN_ALLOW_THREADS
7573 res = mknod(filename, mode, device);
7574 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007575 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007576 if (res < 0)
7577 return posix_error();
7578 Py_INCREF(Py_None);
7579 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007580}
7581#endif
7582
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007583#ifdef HAVE_DEVICE_MACROS
7584PyDoc_STRVAR(posix_major__doc__,
7585"major(device) -> major number\n\
7586Extracts a device major number from a raw device number.");
7587
7588static PyObject *
7589posix_major(PyObject *self, PyObject *args)
7590{
Victor Stinner8c62be82010-05-06 00:08:46 +00007591 int device;
7592 if (!PyArg_ParseTuple(args, "i:major", &device))
7593 return NULL;
7594 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007595}
7596
7597PyDoc_STRVAR(posix_minor__doc__,
7598"minor(device) -> minor number\n\
7599Extracts a device minor number from a raw device number.");
7600
7601static PyObject *
7602posix_minor(PyObject *self, PyObject *args)
7603{
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 int device;
7605 if (!PyArg_ParseTuple(args, "i:minor", &device))
7606 return NULL;
7607 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007608}
7609
7610PyDoc_STRVAR(posix_makedev__doc__,
7611"makedev(major, minor) -> device number\n\
7612Composes a raw device number from the major and minor device numbers.");
7613
7614static PyObject *
7615posix_makedev(PyObject *self, PyObject *args)
7616{
Victor Stinner8c62be82010-05-06 00:08:46 +00007617 int major, minor;
7618 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7619 return NULL;
7620 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007621}
7622#endif /* device macros */
7623
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007624
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007625#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007626PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007627"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007628Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007629
Barry Warsaw53699e91996-12-10 23:23:01 +00007630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007631posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007632{
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 int fd;
7634 off_t length;
7635 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007636
Ross Lagerwall7807c352011-03-17 20:20:30 +02007637 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007639
Victor Stinner8c62be82010-05-06 00:08:46 +00007640 Py_BEGIN_ALLOW_THREADS
7641 res = ftruncate(fd, length);
7642 Py_END_ALLOW_THREADS
7643 if (res < 0)
7644 return posix_error();
7645 Py_INCREF(Py_None);
7646 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007647}
7648#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007649
Ross Lagerwall7807c352011-03-17 20:20:30 +02007650#ifdef HAVE_TRUNCATE
7651PyDoc_STRVAR(posix_truncate__doc__,
7652"truncate(path, length)\n\n\
7653Truncate the file given by path to length bytes.");
7654
7655static PyObject *
7656posix_truncate(PyObject *self, PyObject *args)
7657{
7658 PyObject *opath;
7659 const char *path;
7660 off_t length;
7661 int res;
7662
7663 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7664 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7665 return NULL;
7666 path = PyBytes_AsString(opath);
7667
7668 Py_BEGIN_ALLOW_THREADS
7669 res = truncate(path, length);
7670 Py_END_ALLOW_THREADS
7671 Py_DECREF(opath);
7672 if (res < 0)
7673 return posix_error();
7674 Py_RETURN_NONE;
7675}
7676#endif
7677
7678#ifdef HAVE_POSIX_FALLOCATE
7679PyDoc_STRVAR(posix_posix_fallocate__doc__,
7680"posix_fallocate(fd, offset, len)\n\n\
7681Ensures that enough disk space is allocated for the file specified by fd\n\
7682starting from offset and continuing for len bytes.");
7683
7684static PyObject *
7685posix_posix_fallocate(PyObject *self, PyObject *args)
7686{
7687 off_t len, offset;
7688 int res, fd;
7689
7690 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7691 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7692 return NULL;
7693
7694 Py_BEGIN_ALLOW_THREADS
7695 res = posix_fallocate(fd, offset, len);
7696 Py_END_ALLOW_THREADS
7697 if (res != 0) {
7698 errno = res;
7699 return posix_error();
7700 }
7701 Py_RETURN_NONE;
7702}
7703#endif
7704
7705#ifdef HAVE_POSIX_FADVISE
7706PyDoc_STRVAR(posix_posix_fadvise__doc__,
7707"posix_fadvise(fd, offset, len, advice)\n\n\
7708Announces an intention to access data in a specific pattern thus allowing\n\
7709the kernel to make optimizations.\n\
7710The advice applies to the region of the file specified by fd starting at\n\
7711offset and continuing for len bytes.\n\
7712advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7713POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7714POSIX_FADV_DONTNEED.");
7715
7716static PyObject *
7717posix_posix_fadvise(PyObject *self, PyObject *args)
7718{
7719 off_t len, offset;
7720 int res, fd, advice;
7721
7722 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7723 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7724 return NULL;
7725
7726 Py_BEGIN_ALLOW_THREADS
7727 res = posix_fadvise(fd, offset, len, advice);
7728 Py_END_ALLOW_THREADS
7729 if (res != 0) {
7730 errno = res;
7731 return posix_error();
7732 }
7733 Py_RETURN_NONE;
7734}
7735#endif
7736
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007737#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007738PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007739"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007740Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007741
Fred Drake762e2061999-08-26 17:23:54 +00007742/* Save putenv() parameters as values here, so we can collect them when they
7743 * get re-set with another call for the same key. */
7744static PyObject *posix_putenv_garbage;
7745
Tim Peters5aa91602002-01-30 05:46:57 +00007746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007747posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007748{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007749#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 wchar_t *s1, *s2;
7751 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007752#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 PyObject *os1, *os2;
7754 char *s1, *s2;
7755 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007756#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007757 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007758 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007759
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007760#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 if (!PyArg_ParseTuple(args,
7762 "uu:putenv",
7763 &s1, &s2))
7764 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00007765#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 if (!PyArg_ParseTuple(args,
7767 "O&O&:putenv",
7768 PyUnicode_FSConverter, &os1,
7769 PyUnicode_FSConverter, &os2))
7770 return NULL;
7771 s1 = PyBytes_AsString(os1);
7772 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007773#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007774
7775#if defined(PYOS_OS2)
7776 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7777 APIRET rc;
7778
Guido van Rossumd48f2521997-12-05 22:19:34 +00007779 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00007780 if (rc != NO_ERROR) {
7781 os2_error(rc);
7782 goto error;
7783 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007784
7785 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7786 APIRET rc;
7787
Guido van Rossumd48f2521997-12-05 22:19:34 +00007788 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00007789 if (rc != NO_ERROR) {
7790 os2_error(rc);
7791 goto error;
7792 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007793 } else {
7794#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 /* XXX This can leak memory -- not easy to fix :-( */
7796 /* len includes space for a trailing \0; the size arg to
7797 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007798#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 len = wcslen(s1) + wcslen(s2) + 2;
7800 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007801#else
Victor Stinner84ae1182010-05-06 22:05:07 +00007802 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007804#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007805 if (newstr == NULL) {
7806 PyErr_NoMemory();
7807 goto error;
7808 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007809#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02007811 if (newenv == NULL)
7812 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 _snwprintf(newenv, len, L"%s=%s", s1, s2);
7814 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007816 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007818#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 newenv = PyBytes_AS_STRING(newstr);
7820 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7821 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007823 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007825#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007826
Victor Stinner8c62be82010-05-06 00:08:46 +00007827 /* Install the first arg and newstr in posix_putenv_garbage;
7828 * this will cause previous value to be collected. This has to
7829 * happen after the real putenv() call because the old value
7830 * was still accessible until then. */
7831 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00007832#ifdef MS_WINDOWS
7833 PyTuple_GET_ITEM(args, 0),
7834#else
7835 os1,
7836#endif
7837 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 /* really not much we can do; just leak */
7839 PyErr_Clear();
7840 }
7841 else {
7842 Py_DECREF(newstr);
7843 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007844
7845#if defined(PYOS_OS2)
7846 }
7847#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007848
Martin v. Löwis011e8422009-05-05 04:43:17 +00007849#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007850 Py_DECREF(os1);
7851 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007852#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007853 Py_RETURN_NONE;
7854
7855error:
7856#ifndef MS_WINDOWS
7857 Py_DECREF(os1);
7858 Py_DECREF(os2);
7859#endif
7860 Py_XDECREF(newstr);
7861 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007862}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007863#endif /* putenv */
7864
Guido van Rossumc524d952001-10-19 01:31:59 +00007865#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007866PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007867"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007868Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007869
7870static PyObject *
7871posix_unsetenv(PyObject *self, PyObject *args)
7872{
Victor Stinner84ae1182010-05-06 22:05:07 +00007873#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007874 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00007875
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7877 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00007878#else
7879 PyObject *os1;
7880 char *s1;
7881
7882 if (!PyArg_ParseTuple(args, "O&:unsetenv",
7883 PyUnicode_FSConverter, &os1))
7884 return NULL;
7885 s1 = PyBytes_AsString(os1);
7886#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007887
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00007889
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 /* Remove the key from posix_putenv_garbage;
7891 * this will cause it to be collected. This has to
7892 * happen after the real unsetenv() call because the
7893 * old value was still accessible until then.
7894 */
7895 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00007896#ifdef MS_WINDOWS
7897 PyTuple_GET_ITEM(args, 0)
7898#else
7899 os1
7900#endif
7901 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 /* really not much we can do; just leak */
7903 PyErr_Clear();
7904 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007905
Victor Stinner84ae1182010-05-06 22:05:07 +00007906#ifndef MS_WINDOWS
7907 Py_DECREF(os1);
7908#endif
7909 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007910}
7911#endif /* unsetenv */
7912
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007913PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007914"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007915Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007916
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007918posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007919{
Victor Stinner8c62be82010-05-06 00:08:46 +00007920 int code;
7921 char *message;
7922 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7923 return NULL;
7924 message = strerror(code);
7925 if (message == NULL) {
7926 PyErr_SetString(PyExc_ValueError,
7927 "strerror() argument out of range");
7928 return NULL;
7929 }
7930 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007931}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007932
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007933
Guido van Rossumc9641791998-08-04 15:26:23 +00007934#ifdef HAVE_SYS_WAIT_H
7935
Fred Drake106c1a02002-04-23 15:58:02 +00007936#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007937PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007938"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007939Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007940
7941static PyObject *
7942posix_WCOREDUMP(PyObject *self, PyObject *args)
7943{
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 WAIT_TYPE status;
7945 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007946
Victor Stinner8c62be82010-05-06 00:08:46 +00007947 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7948 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007949
Victor Stinner8c62be82010-05-06 00:08:46 +00007950 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007951}
7952#endif /* WCOREDUMP */
7953
7954#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007955PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007956"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007957Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007958job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007959
7960static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007961posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007962{
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 WAIT_TYPE status;
7964 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007965
Victor Stinner8c62be82010-05-06 00:08:46 +00007966 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7967 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007968
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007970}
7971#endif /* WIFCONTINUED */
7972
Guido van Rossumc9641791998-08-04 15:26:23 +00007973#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007974PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007975"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007976Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007977
7978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007979posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007980{
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 WAIT_TYPE status;
7982 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007983
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7985 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007986
Victor Stinner8c62be82010-05-06 00:08:46 +00007987 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007988}
7989#endif /* WIFSTOPPED */
7990
7991#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007992PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007993"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007994Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007995
7996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007997posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007998{
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 WAIT_TYPE status;
8000 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008001
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8003 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008004
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008006}
8007#endif /* WIFSIGNALED */
8008
8009#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008010PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008011"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008012Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008013system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008014
8015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008016posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008017{
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 WAIT_TYPE status;
8019 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008020
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8022 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008023
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008025}
8026#endif /* WIFEXITED */
8027
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008028#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008029PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008030"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008031Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008032
8033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008034posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008035{
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 WAIT_TYPE status;
8037 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008038
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8040 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008041
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008043}
8044#endif /* WEXITSTATUS */
8045
8046#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008047PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008048"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008049Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008050value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008051
8052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008053posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008054{
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 WAIT_TYPE status;
8056 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008057
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8059 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008060
Victor Stinner8c62be82010-05-06 00:08:46 +00008061 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008062}
8063#endif /* WTERMSIG */
8064
8065#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008066PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008067"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008068Return the signal that stopped the process that provided\n\
8069the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008070
8071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008072posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008073{
Victor Stinner8c62be82010-05-06 00:08:46 +00008074 WAIT_TYPE status;
8075 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008076
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8078 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008079
Victor Stinner8c62be82010-05-06 00:08:46 +00008080 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008081}
8082#endif /* WSTOPSIG */
8083
8084#endif /* HAVE_SYS_WAIT_H */
8085
8086
Thomas Wouters477c8d52006-05-27 19:21:47 +00008087#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008088#ifdef _SCO_DS
8089/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8090 needed definitions in sys/statvfs.h */
8091#define _SVID3
8092#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008093#include <sys/statvfs.h>
8094
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008095static PyObject*
8096_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8098 if (v == NULL)
8099 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008100
8101#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008102 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8103 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8104 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8105 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8106 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8107 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8108 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8109 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8110 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8111 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008112#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008113 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8114 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8115 PyStructSequence_SET_ITEM(v, 2,
8116 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8117 PyStructSequence_SET_ITEM(v, 3,
8118 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8119 PyStructSequence_SET_ITEM(v, 4,
8120 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8121 PyStructSequence_SET_ITEM(v, 5,
8122 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8123 PyStructSequence_SET_ITEM(v, 6,
8124 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8125 PyStructSequence_SET_ITEM(v, 7,
8126 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8127 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8128 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008129#endif
8130
Victor Stinner8c62be82010-05-06 00:08:46 +00008131 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008132}
8133
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008134PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008135"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008136Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008137
8138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008139posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008140{
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 int fd, res;
8142 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008143
Victor Stinner8c62be82010-05-06 00:08:46 +00008144 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8145 return NULL;
8146 Py_BEGIN_ALLOW_THREADS
8147 res = fstatvfs(fd, &st);
8148 Py_END_ALLOW_THREADS
8149 if (res != 0)
8150 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008151
Victor Stinner8c62be82010-05-06 00:08:46 +00008152 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008153}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008154#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008155
8156
Thomas Wouters477c8d52006-05-27 19:21:47 +00008157#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008158#include <sys/statvfs.h>
8159
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008160PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008161"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008162Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008163
8164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008165posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008166{
Victor Stinner6fa67772011-09-20 04:04:33 +02008167 PyObject *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008168 int res;
8169 struct statvfs st;
Victor Stinner6fa67772011-09-20 04:04:33 +02008170 if (!PyArg_ParseTuple(args, "O&:statvfs", PyUnicode_FSConverter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00008171 return NULL;
8172 Py_BEGIN_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008173 res = statvfs(PyBytes_AS_STRING(path), &st);
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 Py_END_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008175 if (res != 0) {
8176 posix_error_with_filename(PyBytes_AS_STRING(path));
8177 Py_DECREF(path);
8178 return NULL;
8179 }
8180 Py_DECREF(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008181
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008183}
8184#endif /* HAVE_STATVFS */
8185
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008186#ifdef MS_WINDOWS
8187PyDoc_STRVAR(win32__getdiskusage__doc__,
8188"_getdiskusage(path) -> (total, free)\n\n\
8189Return disk usage statistics about the given path as (total, free) tuple.");
8190
8191static PyObject *
8192win32__getdiskusage(PyObject *self, PyObject *args)
8193{
8194 BOOL retval;
8195 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008196 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008197
Victor Stinner6139c1b2011-11-09 22:14:14 +01008198 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008199 return NULL;
8200
8201 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008202 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008203 Py_END_ALLOW_THREADS
8204 if (retval == 0)
8205 return PyErr_SetFromWindowsErr(0);
8206
8207 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8208}
8209#endif
8210
8211
Fred Drakec9680921999-12-13 16:37:25 +00008212/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8213 * It maps strings representing configuration variable names to
8214 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008215 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008216 * rarely-used constants. There are three separate tables that use
8217 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008218 *
8219 * This code is always included, even if none of the interfaces that
8220 * need it are included. The #if hackery needed to avoid it would be
8221 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008222 */
8223struct constdef {
8224 char *name;
8225 long value;
8226};
8227
Fred Drake12c6e2d1999-12-14 21:25:03 +00008228static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008229conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008230 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008231{
Christian Heimes217cfd12007-12-02 14:31:20 +00008232 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008233 *valuep = PyLong_AS_LONG(arg);
8234 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008235 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008236 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008237 /* look up the value in the table using a binary search */
8238 size_t lo = 0;
8239 size_t mid;
8240 size_t hi = tablesize;
8241 int cmp;
8242 const char *confname;
8243 if (!PyUnicode_Check(arg)) {
8244 PyErr_SetString(PyExc_TypeError,
8245 "configuration names must be strings or integers");
8246 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008248 confname = _PyUnicode_AsString(arg);
8249 if (confname == NULL)
8250 return 0;
8251 while (lo < hi) {
8252 mid = (lo + hi) / 2;
8253 cmp = strcmp(confname, table[mid].name);
8254 if (cmp < 0)
8255 hi = mid;
8256 else if (cmp > 0)
8257 lo = mid + 1;
8258 else {
8259 *valuep = table[mid].value;
8260 return 1;
8261 }
8262 }
8263 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8264 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008265 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008266}
8267
8268
8269#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8270static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008271#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008272 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008273#endif
8274#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008275 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008276#endif
Fred Drakec9680921999-12-13 16:37:25 +00008277#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008278 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008279#endif
8280#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008281 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008282#endif
8283#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008284 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008285#endif
8286#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008287 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008288#endif
8289#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008291#endif
8292#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008293 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008294#endif
8295#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008296 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008297#endif
8298#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008299 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008300#endif
8301#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008302 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008303#endif
8304#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008305 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008306#endif
8307#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008309#endif
8310#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008312#endif
8313#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008315#endif
8316#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008317 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008318#endif
8319#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008320 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008321#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008322#ifdef _PC_ACL_ENABLED
8323 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8324#endif
8325#ifdef _PC_MIN_HOLE_SIZE
8326 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8327#endif
8328#ifdef _PC_ALLOC_SIZE_MIN
8329 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8330#endif
8331#ifdef _PC_REC_INCR_XFER_SIZE
8332 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8333#endif
8334#ifdef _PC_REC_MAX_XFER_SIZE
8335 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8336#endif
8337#ifdef _PC_REC_MIN_XFER_SIZE
8338 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8339#endif
8340#ifdef _PC_REC_XFER_ALIGN
8341 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8342#endif
8343#ifdef _PC_SYMLINK_MAX
8344 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8345#endif
8346#ifdef _PC_XATTR_ENABLED
8347 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8348#endif
8349#ifdef _PC_XATTR_EXISTS
8350 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8351#endif
8352#ifdef _PC_TIMESTAMP_RESOLUTION
8353 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8354#endif
Fred Drakec9680921999-12-13 16:37:25 +00008355};
8356
Fred Drakec9680921999-12-13 16:37:25 +00008357static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008358conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008359{
8360 return conv_confname(arg, valuep, posix_constants_pathconf,
8361 sizeof(posix_constants_pathconf)
8362 / sizeof(struct constdef));
8363}
8364#endif
8365
8366#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008367PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008368"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008369Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008370If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008371
8372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008373posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008374{
8375 PyObject *result = NULL;
8376 int name, fd;
8377
Fred Drake12c6e2d1999-12-14 21:25:03 +00008378 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8379 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008380 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008381
Stefan Krah0e803b32010-11-26 16:16:47 +00008382 errno = 0;
8383 limit = fpathconf(fd, name);
8384 if (limit == -1 && errno != 0)
8385 posix_error();
8386 else
8387 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008388 }
8389 return result;
8390}
8391#endif
8392
8393
8394#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008395PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008396"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008397Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008398If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008399
8400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008401posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008402{
8403 PyObject *result = NULL;
8404 int name;
8405 char *path;
8406
8407 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8408 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008410
Victor Stinner8c62be82010-05-06 00:08:46 +00008411 errno = 0;
8412 limit = pathconf(path, name);
8413 if (limit == -1 && errno != 0) {
8414 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008415 /* could be a path or name problem */
8416 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008417 else
Stefan Krah99439262010-11-26 12:58:05 +00008418 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 }
8420 else
8421 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008422 }
8423 return result;
8424}
8425#endif
8426
8427#ifdef HAVE_CONFSTR
8428static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008429#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008430 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008431#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008432#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008433 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008434#endif
8435#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008436 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008437#endif
Fred Draked86ed291999-12-15 15:34:33 +00008438#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008439 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008440#endif
8441#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008442 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008443#endif
8444#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008446#endif
8447#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008448 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008449#endif
Fred Drakec9680921999-12-13 16:37:25 +00008450#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008451 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008452#endif
8453#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008454 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008455#endif
8456#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008457 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008458#endif
8459#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008460 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008461#endif
8462#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008463 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008464#endif
8465#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008466 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008467#endif
8468#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008470#endif
8471#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008473#endif
Fred Draked86ed291999-12-15 15:34:33 +00008474#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008475 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008476#endif
Fred Drakec9680921999-12-13 16:37:25 +00008477#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008478 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008479#endif
Fred Draked86ed291999-12-15 15:34:33 +00008480#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008481 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008482#endif
8483#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008485#endif
8486#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008488#endif
8489#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008490 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008491#endif
Fred Drakec9680921999-12-13 16:37:25 +00008492#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008494#endif
8495#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008497#endif
8498#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008499 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008500#endif
8501#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008503#endif
8504#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008505 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008506#endif
8507#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008508 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008509#endif
8510#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008512#endif
8513#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008514 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008515#endif
8516#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008517 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008518#endif
8519#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008521#endif
8522#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008523 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008524#endif
8525#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008526 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008527#endif
8528#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008529 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008530#endif
8531#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008532 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008533#endif
8534#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008535 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008536#endif
8537#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008538 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008539#endif
Fred Draked86ed291999-12-15 15:34:33 +00008540#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008541 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008542#endif
8543#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008544 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008545#endif
8546#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008547 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008548#endif
8549#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008550 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008551#endif
8552#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008553 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008554#endif
8555#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008556 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008557#endif
8558#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008559 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008560#endif
8561#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008562 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008563#endif
8564#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008565 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008566#endif
8567#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008568 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008569#endif
8570#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008571 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008572#endif
8573#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008574 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008575#endif
8576#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008577 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008578#endif
Fred Drakec9680921999-12-13 16:37:25 +00008579};
8580
8581static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008582conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008583{
8584 return conv_confname(arg, valuep, posix_constants_confstr,
8585 sizeof(posix_constants_confstr)
8586 / sizeof(struct constdef));
8587}
8588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008589PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008590"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008591Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008592
8593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008594posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008595{
8596 PyObject *result = NULL;
8597 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008598 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008599 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008600
Victor Stinnercb043522010-09-10 23:49:04 +00008601 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8602 return NULL;
8603
8604 errno = 0;
8605 len = confstr(name, buffer, sizeof(buffer));
8606 if (len == 0) {
8607 if (errno) {
8608 posix_error();
8609 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008610 }
8611 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008612 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008613 }
8614 }
Victor Stinnercb043522010-09-10 23:49:04 +00008615
8616 if ((unsigned int)len >= sizeof(buffer)) {
8617 char *buf = PyMem_Malloc(len);
8618 if (buf == NULL)
8619 return PyErr_NoMemory();
8620 confstr(name, buf, len);
8621 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8622 PyMem_Free(buf);
8623 }
8624 else
8625 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008626 return result;
8627}
8628#endif
8629
8630
8631#ifdef HAVE_SYSCONF
8632static struct constdef posix_constants_sysconf[] = {
8633#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008634 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008635#endif
8636#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008637 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008638#endif
8639#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008640 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008641#endif
8642#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008643 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008644#endif
8645#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008646 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008647#endif
8648#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008649 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008650#endif
8651#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008652 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008653#endif
8654#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008655 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008656#endif
8657#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008658 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008659#endif
8660#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008661 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008662#endif
Fred Draked86ed291999-12-15 15:34:33 +00008663#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008664 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008665#endif
8666#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008667 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008668#endif
Fred Drakec9680921999-12-13 16:37:25 +00008669#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008670 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008671#endif
Fred Drakec9680921999-12-13 16:37:25 +00008672#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008673 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008674#endif
8675#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008676 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008677#endif
8678#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008679 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008680#endif
8681#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008682 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008683#endif
8684#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008685 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008686#endif
Fred Draked86ed291999-12-15 15:34:33 +00008687#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008688 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008689#endif
Fred Drakec9680921999-12-13 16:37:25 +00008690#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008691 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008692#endif
8693#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008694 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008695#endif
8696#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008697 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008698#endif
8699#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008700 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008701#endif
8702#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008703 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008704#endif
Fred Draked86ed291999-12-15 15:34:33 +00008705#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008706 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008707#endif
Fred Drakec9680921999-12-13 16:37:25 +00008708#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008709 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008710#endif
8711#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008712 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008713#endif
8714#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008715 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008716#endif
8717#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008718 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008719#endif
8720#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008721 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008722#endif
8723#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008724 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008725#endif
8726#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008727 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008728#endif
8729#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008730 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008731#endif
8732#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008733 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008734#endif
8735#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008736 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008737#endif
8738#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008739 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008740#endif
8741#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008742 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008743#endif
8744#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008745 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008746#endif
8747#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008748 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008749#endif
8750#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008751 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008752#endif
8753#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008754 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008755#endif
8756#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008757 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008758#endif
8759#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008760 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008761#endif
8762#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008763 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008764#endif
8765#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008766 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008767#endif
8768#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008770#endif
8771#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008772 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008773#endif
8774#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008775 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008776#endif
Fred Draked86ed291999-12-15 15:34:33 +00008777#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008778 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008779#endif
Fred Drakec9680921999-12-13 16:37:25 +00008780#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008781 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008782#endif
8783#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008784 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008785#endif
8786#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008787 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008788#endif
Fred Draked86ed291999-12-15 15:34:33 +00008789#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008790 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008791#endif
Fred Drakec9680921999-12-13 16:37:25 +00008792#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008793 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008794#endif
Fred Draked86ed291999-12-15 15:34:33 +00008795#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008796 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008797#endif
8798#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008799 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008800#endif
Fred Drakec9680921999-12-13 16:37:25 +00008801#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008802 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008803#endif
8804#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008805 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008806#endif
8807#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008808 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008809#endif
8810#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008811 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008812#endif
Fred Draked86ed291999-12-15 15:34:33 +00008813#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008814 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008815#endif
Fred Drakec9680921999-12-13 16:37:25 +00008816#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008817 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008818#endif
8819#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008821#endif
8822#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008823 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008824#endif
8825#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008826 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008827#endif
8828#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008829 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008830#endif
8831#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008832 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008833#endif
8834#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008835 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008836#endif
Fred Draked86ed291999-12-15 15:34:33 +00008837#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008838 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008839#endif
Fred Drakec9680921999-12-13 16:37:25 +00008840#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008841 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008842#endif
8843#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008845#endif
Fred Draked86ed291999-12-15 15:34:33 +00008846#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008847 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008848#endif
Fred Drakec9680921999-12-13 16:37:25 +00008849#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008851#endif
8852#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008853 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008854#endif
8855#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008856 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008857#endif
8858#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008859 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008860#endif
8861#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008862 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008863#endif
8864#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008865 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008866#endif
8867#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008868 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008869#endif
8870#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008871 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008872#endif
8873#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008874 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008875#endif
Fred Draked86ed291999-12-15 15:34:33 +00008876#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008877 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008878#endif
8879#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008880 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008881#endif
Fred Drakec9680921999-12-13 16:37:25 +00008882#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008883 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008884#endif
8885#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008886 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008887#endif
8888#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008889 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008890#endif
8891#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008892 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008893#endif
8894#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008896#endif
8897#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008898 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008899#endif
8900#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008902#endif
8903#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008904 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008905#endif
8906#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008907 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008908#endif
8909#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008910 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008911#endif
8912#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008913 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008914#endif
8915#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008916 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008917#endif
8918#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008919 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008920#endif
8921#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008922 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008923#endif
8924#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008925 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008926#endif
8927#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008928 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008929#endif
8930#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008931 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008932#endif
8933#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008934 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008935#endif
8936#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008937 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008938#endif
8939#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008940 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008941#endif
8942#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008943 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008944#endif
8945#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008946 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008947#endif
8948#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008949 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008950#endif
8951#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008952 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008953#endif
8954#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008955 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008956#endif
8957#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008958 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008959#endif
8960#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008961 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008962#endif
8963#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008964 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008965#endif
8966#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008967 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008968#endif
8969#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008970 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008971#endif
8972#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008973 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008974#endif
8975#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008976 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008977#endif
8978#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008979 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008980#endif
8981#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008982 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008983#endif
8984#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008985 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008986#endif
Fred Draked86ed291999-12-15 15:34:33 +00008987#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00008988 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008989#endif
Fred Drakec9680921999-12-13 16:37:25 +00008990#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00008991 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008992#endif
8993#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008994 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008995#endif
8996#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00008997 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008998#endif
8999#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009000 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009001#endif
9002#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009003 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009004#endif
9005#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009006 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009007#endif
9008#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009009 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009010#endif
9011#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009012 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009013#endif
9014#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009016#endif
9017#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009018 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009019#endif
9020#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009021 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009022#endif
9023#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009024 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009025#endif
9026#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009027 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009028#endif
9029#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009030 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009031#endif
9032#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009033 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009034#endif
9035#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009037#endif
9038#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009039 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009040#endif
9041#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009043#endif
9044#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009045 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009046#endif
9047#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009048 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009049#endif
9050#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009052#endif
9053#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009054 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009055#endif
9056#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009058#endif
9059#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009060 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009061#endif
9062#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009063 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009064#endif
9065#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009067#endif
9068#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009070#endif
9071#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009072 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009073#endif
9074#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009076#endif
9077#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009078 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009079#endif
9080#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009082#endif
9083#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009084 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009085#endif
9086#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009088#endif
9089#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009090 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009091#endif
9092#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009093 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009094#endif
9095#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009096 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009097#endif
9098#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009099 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009100#endif
9101#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009102 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009103#endif
9104#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009105 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009106#endif
9107#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009109#endif
9110#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009112#endif
9113#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009114 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009115#endif
9116#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009118#endif
9119#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009120 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009121#endif
9122#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009123 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009124#endif
9125};
9126
9127static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009128conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009129{
9130 return conv_confname(arg, valuep, posix_constants_sysconf,
9131 sizeof(posix_constants_sysconf)
9132 / sizeof(struct constdef));
9133}
9134
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009135PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009136"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009137Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009138
9139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009140posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009141{
9142 PyObject *result = NULL;
9143 int name;
9144
9145 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9146 int value;
9147
9148 errno = 0;
9149 value = sysconf(name);
9150 if (value == -1 && errno != 0)
9151 posix_error();
9152 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009153 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009154 }
9155 return result;
9156}
9157#endif
9158
9159
Fred Drakebec628d1999-12-15 18:31:10 +00009160/* This code is used to ensure that the tables of configuration value names
9161 * are in sorted order as required by conv_confname(), and also to build the
9162 * the exported dictionaries that are used to publish information about the
9163 * names available on the host platform.
9164 *
9165 * Sorting the table at runtime ensures that the table is properly ordered
9166 * when used, even for platforms we're not able to test on. It also makes
9167 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009168 */
Fred Drakebec628d1999-12-15 18:31:10 +00009169
9170static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009171cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009172{
9173 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009174 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009175 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009176 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009177
9178 return strcmp(c1->name, c2->name);
9179}
9180
9181static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009182setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009184{
Fred Drakebec628d1999-12-15 18:31:10 +00009185 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009186 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009187
9188 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9189 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009190 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009191 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009192
Barry Warsaw3155db32000-04-13 15:20:40 +00009193 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009194 PyObject *o = PyLong_FromLong(table[i].value);
9195 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9196 Py_XDECREF(o);
9197 Py_DECREF(d);
9198 return -1;
9199 }
9200 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009201 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009202 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009203}
9204
Fred Drakebec628d1999-12-15 18:31:10 +00009205/* Return -1 on failure, 0 on success. */
9206static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009207setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009208{
9209#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009210 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009211 sizeof(posix_constants_pathconf)
9212 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009213 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009214 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009215#endif
9216#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009217 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009218 sizeof(posix_constants_confstr)
9219 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009220 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009221 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009222#endif
9223#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009224 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009225 sizeof(posix_constants_sysconf)
9226 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009227 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009228 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009229#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009230 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009231}
Fred Draked86ed291999-12-15 15:34:33 +00009232
9233
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009234PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009235"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009236Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009237in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009238
9239static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009240posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009241{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009242 abort();
9243 /*NOTREACHED*/
9244 Py_FatalError("abort() called from Python code didn't abort!");
9245 return NULL;
9246}
Fred Drakebec628d1999-12-15 18:31:10 +00009247
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009248#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009249PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009250"startfile(filepath [, operation]) - Start a file with its associated\n\
9251application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009252\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009253When \"operation\" is not specified or \"open\", this acts like\n\
9254double-clicking the file in Explorer, or giving the file name as an\n\
9255argument to the DOS \"start\" command: the file is opened with whatever\n\
9256application (if any) its extension is associated.\n\
9257When another \"operation\" is given, it specifies what should be done with\n\
9258the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009259\n\
9260startfile returns as soon as the associated application is launched.\n\
9261There is no option to wait for the application to close, and no way\n\
9262to retrieve the application's exit status.\n\
9263\n\
9264The filepath is relative to the current directory. If you want to use\n\
9265an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009266the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009267
9268static PyObject *
9269win32_startfile(PyObject *self, PyObject *args)
9270{
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 PyObject *ofilepath;
9272 char *filepath;
9273 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009274 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009275 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009276
Victor Stinnereb5657a2011-09-30 01:44:27 +02009277 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009278 if (!PyArg_ParseTuple(args, "U|s:startfile",
9279 &unipath, &operation)) {
9280 PyErr_Clear();
9281 goto normal;
9282 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009283
Victor Stinner8c62be82010-05-06 00:08:46 +00009284 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009285 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009286 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009287 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 PyErr_Clear();
9289 operation = NULL;
9290 goto normal;
9291 }
9292 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009293
Victor Stinnereb5657a2011-09-30 01:44:27 +02009294 wpath = PyUnicode_AsUnicode(unipath);
9295 if (wpath == NULL)
9296 goto normal;
9297 if (uoperation) {
9298 woperation = PyUnicode_AsUnicode(uoperation);
9299 if (woperation == NULL)
9300 goto normal;
9301 }
9302 else
9303 woperation = NULL;
9304
Victor Stinner8c62be82010-05-06 00:08:46 +00009305 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009306 rc = ShellExecuteW((HWND)0, woperation, wpath,
9307 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009308 Py_END_ALLOW_THREADS
9309
Victor Stinnereb5657a2011-09-30 01:44:27 +02009310 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009311 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009312 win32_error_object("startfile", unipath);
9313 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009314 }
9315 Py_INCREF(Py_None);
9316 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009317
9318normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9320 PyUnicode_FSConverter, &ofilepath,
9321 &operation))
9322 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009323 if (win32_warn_bytes_api()) {
9324 Py_DECREF(ofilepath);
9325 return NULL;
9326 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 filepath = PyBytes_AsString(ofilepath);
9328 Py_BEGIN_ALLOW_THREADS
9329 rc = ShellExecute((HWND)0, operation, filepath,
9330 NULL, NULL, SW_SHOWNORMAL);
9331 Py_END_ALLOW_THREADS
9332 if (rc <= (HINSTANCE)32) {
9333 PyObject *errval = win32_error("startfile", filepath);
9334 Py_DECREF(ofilepath);
9335 return errval;
9336 }
9337 Py_DECREF(ofilepath);
9338 Py_INCREF(Py_None);
9339 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009340}
9341#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009342
Martin v. Löwis438b5342002-12-27 10:16:42 +00009343#ifdef HAVE_GETLOADAVG
9344PyDoc_STRVAR(posix_getloadavg__doc__,
9345"getloadavg() -> (float, float, float)\n\n\
9346Return the number of processes in the system run queue averaged over\n\
9347the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9348was unobtainable");
9349
9350static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009351posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009352{
9353 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009354 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009355 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9356 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009357 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009358 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009359}
9360#endif
9361
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009362#ifdef MS_WINDOWS
9363
9364PyDoc_STRVAR(win32_urandom__doc__,
9365"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009366Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009367
9368typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
9369 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
9370 DWORD dwFlags );
9371typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
9372 BYTE *pbBuffer );
9373
9374static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00009375/* This handle is never explicitly released. Instead, the operating
9376 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009377static HCRYPTPROV hCryptProv = 0;
9378
Tim Peters4ad82172004-08-30 17:02:04 +00009379static PyObject*
9380win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009381{
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 int howMany;
9383 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009384
Victor Stinner8c62be82010-05-06 00:08:46 +00009385 /* Read arguments */
9386 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9387 return NULL;
9388 if (howMany < 0)
9389 return PyErr_Format(PyExc_ValueError,
9390 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009391
Victor Stinner8c62be82010-05-06 00:08:46 +00009392 if (hCryptProv == 0) {
9393 HINSTANCE hAdvAPI32 = NULL;
9394 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009395
Victor Stinner8c62be82010-05-06 00:08:46 +00009396 /* Obtain handle to the DLL containing CryptoAPI
9397 This should not fail */
9398 hAdvAPI32 = GetModuleHandle("advapi32.dll");
9399 if(hAdvAPI32 == NULL)
9400 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009401
Victor Stinner8c62be82010-05-06 00:08:46 +00009402 /* Obtain pointers to the CryptoAPI functions
9403 This will fail on some early versions of Win95 */
9404 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
9405 hAdvAPI32,
9406 "CryptAcquireContextA");
9407 if (pCryptAcquireContext == NULL)
9408 return PyErr_Format(PyExc_NotImplementedError,
9409 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009410
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
9412 hAdvAPI32, "CryptGenRandom");
9413 if (pCryptGenRandom == NULL)
9414 return PyErr_Format(PyExc_NotImplementedError,
9415 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009416
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 /* Acquire context */
9418 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
9419 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
9420 return win32_error("CryptAcquireContext", NULL);
9421 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009422
Victor Stinner8c62be82010-05-06 00:08:46 +00009423 /* Allocate bytes */
9424 result = PyBytes_FromStringAndSize(NULL, howMany);
9425 if (result != NULL) {
9426 /* Get random data */
9427 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
9428 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
9429 PyBytes_AS_STRING(result))) {
9430 Py_DECREF(result);
9431 return win32_error("CryptGenRandom", NULL);
9432 }
9433 }
9434 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009435}
9436#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009437
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009438PyDoc_STRVAR(device_encoding__doc__,
9439"device_encoding(fd) -> str\n\n\
9440Return a string describing the encoding of the device\n\
9441if the output is a terminal; else return None.");
9442
9443static PyObject *
9444device_encoding(PyObject *self, PyObject *args)
9445{
Victor Stinner8c62be82010-05-06 00:08:46 +00009446 int fd;
Victor Stinner7870bdf2011-05-23 18:12:52 +02009447#if defined(MS_WINDOWS) || defined(MS_WIN64)
9448 UINT cp;
9449#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9451 return NULL;
9452 if (!_PyVerify_fd(fd) || !isatty(fd)) {
9453 Py_INCREF(Py_None);
9454 return Py_None;
9455 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009456#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner7870bdf2011-05-23 18:12:52 +02009457 if (fd == 0)
9458 cp = GetConsoleCP();
9459 else if (fd == 1 || fd == 2)
9460 cp = GetConsoleOutputCP();
9461 else
9462 cp = 0;
9463 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
9464 has no console */
9465 if (cp != 0)
9466 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009467#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 {
9469 char *codeset = nl_langinfo(CODESET);
9470 if (codeset != NULL && codeset[0] != 0)
9471 return PyUnicode_FromString(codeset);
9472 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009473#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 Py_INCREF(Py_None);
9475 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009476}
9477
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009478#ifdef __VMS
9479/* Use openssl random routine */
9480#include <openssl/rand.h>
9481PyDoc_STRVAR(vms_urandom__doc__,
9482"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009483Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009484
9485static PyObject*
9486vms_urandom(PyObject *self, PyObject *args)
9487{
Victor Stinner8c62be82010-05-06 00:08:46 +00009488 int howMany;
9489 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009490
Victor Stinner8c62be82010-05-06 00:08:46 +00009491 /* Read arguments */
9492 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9493 return NULL;
9494 if (howMany < 0)
9495 return PyErr_Format(PyExc_ValueError,
9496 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009497
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 /* Allocate bytes */
9499 result = PyBytes_FromStringAndSize(NULL, howMany);
9500 if (result != NULL) {
9501 /* Get random data */
9502 if (RAND_pseudo_bytes((unsigned char*)
9503 PyBytes_AS_STRING(result),
9504 howMany) < 0) {
9505 Py_DECREF(result);
9506 return PyErr_Format(PyExc_ValueError,
9507 "RAND_pseudo_bytes");
9508 }
9509 }
9510 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009511}
9512#endif
9513
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009514#ifdef HAVE_SETRESUID
9515PyDoc_STRVAR(posix_setresuid__doc__,
9516"setresuid(ruid, euid, suid)\n\n\
9517Set the current process's real, effective, and saved user ids.");
9518
9519static PyObject*
9520posix_setresuid (PyObject *self, PyObject *args)
9521{
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 /* We assume uid_t is no larger than a long. */
9523 long ruid, euid, suid;
9524 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9525 return NULL;
9526 if (setresuid(ruid, euid, suid) < 0)
9527 return posix_error();
9528 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009529}
9530#endif
9531
9532#ifdef HAVE_SETRESGID
9533PyDoc_STRVAR(posix_setresgid__doc__,
9534"setresgid(rgid, egid, sgid)\n\n\
9535Set the current process's real, effective, and saved group ids.");
9536
9537static PyObject*
9538posix_setresgid (PyObject *self, PyObject *args)
9539{
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 /* We assume uid_t is no larger than a long. */
9541 long rgid, egid, sgid;
9542 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9543 return NULL;
9544 if (setresgid(rgid, egid, sgid) < 0)
9545 return posix_error();
9546 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009547}
9548#endif
9549
9550#ifdef HAVE_GETRESUID
9551PyDoc_STRVAR(posix_getresuid__doc__,
9552"getresuid() -> (ruid, euid, suid)\n\n\
9553Get tuple of the current process's real, effective, and saved user ids.");
9554
9555static PyObject*
9556posix_getresuid (PyObject *self, PyObject *noargs)
9557{
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 uid_t ruid, euid, suid;
9559 long l_ruid, l_euid, l_suid;
9560 if (getresuid(&ruid, &euid, &suid) < 0)
9561 return posix_error();
9562 /* Force the values into long's as we don't know the size of uid_t. */
9563 l_ruid = ruid;
9564 l_euid = euid;
9565 l_suid = suid;
9566 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009567}
9568#endif
9569
9570#ifdef HAVE_GETRESGID
9571PyDoc_STRVAR(posix_getresgid__doc__,
9572"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009573Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009574
9575static PyObject*
9576posix_getresgid (PyObject *self, PyObject *noargs)
9577{
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 uid_t rgid, egid, sgid;
9579 long l_rgid, l_egid, l_sgid;
9580 if (getresgid(&rgid, &egid, &sgid) < 0)
9581 return posix_error();
9582 /* Force the values into long's as we don't know the size of uid_t. */
9583 l_rgid = rgid;
9584 l_egid = egid;
9585 l_sgid = sgid;
9586 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009587}
9588#endif
9589
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009590/* Posix *at family of functions:
9591 faccessat, fchmodat, fchownat, fstatat, futimesat,
9592 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9593 unlinkat, utimensat, mkfifoat */
9594
9595#ifdef HAVE_FACCESSAT
9596PyDoc_STRVAR(posix_faccessat__doc__,
9597"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9598Like access() but if path is relative, it is taken as relative to dirfd.\n\
9599flags is optional and can be constructed by ORing together zero or more\n\
9600of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
9601If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9602is interpreted relative to the current working directory.");
9603
9604static PyObject *
9605posix_faccessat(PyObject *self, PyObject *args)
9606{
9607 PyObject *opath;
9608 char *path;
9609 int mode;
9610 int res;
9611 int dirfd, flags = 0;
9612 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9613 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9614 return NULL;
9615 path = PyBytes_AsString(opath);
9616 Py_BEGIN_ALLOW_THREADS
9617 res = faccessat(dirfd, path, mode, flags);
9618 Py_END_ALLOW_THREADS
9619 Py_DECREF(opath);
9620 return PyBool_FromLong(res == 0);
9621}
9622#endif
9623
9624#ifdef HAVE_FCHMODAT
9625PyDoc_STRVAR(posix_fchmodat__doc__,
9626"fchmodat(dirfd, path, mode, flags=0)\n\n\
9627Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9628flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9629If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9630is interpreted relative to the current working directory.");
9631
9632static PyObject *
9633posix_fchmodat(PyObject *self, PyObject *args)
9634{
9635 int dirfd, mode, res;
9636 int flags = 0;
9637 PyObject *opath;
9638 char *path;
9639
9640 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9641 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9642 return NULL;
9643
9644 path = PyBytes_AsString(opath);
9645
9646 Py_BEGIN_ALLOW_THREADS
9647 res = fchmodat(dirfd, path, mode, flags);
9648 Py_END_ALLOW_THREADS
9649 Py_DECREF(opath);
9650 if (res < 0)
9651 return posix_error();
9652 Py_RETURN_NONE;
9653}
9654#endif /* HAVE_FCHMODAT */
9655
9656#ifdef HAVE_FCHOWNAT
9657PyDoc_STRVAR(posix_fchownat__doc__,
9658"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9659Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9660flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9661If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9662is interpreted relative to the current working directory.");
9663
9664static PyObject *
9665posix_fchownat(PyObject *self, PyObject *args)
9666{
9667 PyObject *opath;
9668 int dirfd, res;
9669 long uid, gid;
9670 int flags = 0;
9671 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009672
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009673 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9674 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9675 return NULL;
9676
9677 path = PyBytes_AsString(opath);
9678
9679 Py_BEGIN_ALLOW_THREADS
9680 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9681 Py_END_ALLOW_THREADS
9682 Py_DECREF(opath);
9683 if (res < 0)
9684 return posix_error();
9685 Py_RETURN_NONE;
9686}
9687#endif /* HAVE_FCHOWNAT */
9688
9689#ifdef HAVE_FSTATAT
9690PyDoc_STRVAR(posix_fstatat__doc__,
9691"fstatat(dirfd, path, flags=0) -> stat result\n\n\
9692Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9693flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9694If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9695is interpreted relative to the current working directory.");
9696
9697static PyObject *
9698posix_fstatat(PyObject *self, PyObject *args)
9699{
9700 PyObject *opath;
9701 char *path;
9702 STRUCT_STAT st;
9703 int dirfd, res, flags = 0;
9704
9705 if (!PyArg_ParseTuple(args, "iO&|i:fstatat",
9706 &dirfd, PyUnicode_FSConverter, &opath, &flags))
9707 return NULL;
9708 path = PyBytes_AsString(opath);
9709
9710 Py_BEGIN_ALLOW_THREADS
9711 res = fstatat(dirfd, path, &st, flags);
9712 Py_END_ALLOW_THREADS
9713 Py_DECREF(opath);
9714 if (res != 0)
9715 return posix_error();
9716
9717 return _pystat_fromstructstat(&st);
9718}
9719#endif
9720
9721#ifdef HAVE_FUTIMESAT
9722PyDoc_STRVAR(posix_futimesat__doc__,
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009723"futimesat(dirfd, path[, (atime, mtime)])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009724Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9725If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9726is interpreted relative to the current working directory.");
9727
9728static PyObject *
9729posix_futimesat(PyObject *self, PyObject *args)
9730{
9731 PyObject *opath;
9732 char *path;
9733 int res, dirfd;
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009734 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009735 time_t atime, mtime;
9736 long ausec, musec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009737
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009738 if (!PyArg_ParseTuple(args, "iO&|O:futimesat",
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009739 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9740 return NULL;
9741 path = PyBytes_AsString(opath);
9742 if (arg == Py_None) {
9743 /* optional time values not given */
9744 Py_BEGIN_ALLOW_THREADS
9745 res = futimesat(dirfd, path, NULL);
9746 Py_END_ALLOW_THREADS
9747 }
9748 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9749 PyErr_SetString(PyExc_TypeError,
9750 "futimesat() arg 3 must be a tuple (atime, mtime)");
9751 Py_DECREF(opath);
9752 return NULL;
9753 }
9754 else {
9755 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009756 &atime, &ausec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009757 Py_DECREF(opath);
9758 return NULL;
9759 }
9760 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009761 &mtime, &musec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009762 Py_DECREF(opath);
9763 return NULL;
9764 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009765
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009766 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009767 {
9768#ifdef HAVE_UTIMENSAT
9769 struct timespec buf[2];
9770 buf[0].tv_sec = atime;
9771 buf[0].tv_nsec = ausec;
9772 buf[1].tv_sec = mtime;
9773 buf[1].tv_nsec = musec;
9774 res = utimensat(dirfd, path, buf, 0);
9775#else
9776 struct timeval buf[2];
9777 buf[0].tv_sec = atime;
9778 buf[0].tv_usec = ausec;
9779 buf[1].tv_sec = mtime;
9780 buf[1].tv_usec = musec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009781 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009782#endif
9783 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009784 Py_END_ALLOW_THREADS
9785 }
9786 Py_DECREF(opath);
9787 if (res < 0) {
9788 return posix_error();
9789 }
9790 Py_RETURN_NONE;
9791}
9792#endif
9793
9794#ifdef HAVE_LINKAT
9795PyDoc_STRVAR(posix_linkat__doc__,
9796"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9797Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9798and if dstpath is relative, it is taken as relative to dstfd.\n\
9799flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9800If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9801srcpath is interpreted relative to the current working directory. This\n\
9802also applies for dstpath.");
9803
9804static PyObject *
9805posix_linkat(PyObject *self, PyObject *args)
9806{
9807 PyObject *osrc, *odst;
9808 char *src, *dst;
9809 int res, srcfd, dstfd;
9810 int flags = 0;
9811
9812 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9813 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9814 return NULL;
9815 src = PyBytes_AsString(osrc);
9816 dst = PyBytes_AsString(odst);
9817 Py_BEGIN_ALLOW_THREADS
9818 res = linkat(srcfd, src, dstfd, dst, flags);
9819 Py_END_ALLOW_THREADS
9820 Py_DECREF(osrc);
9821 Py_DECREF(odst);
9822 if (res < 0)
9823 return posix_error();
9824 Py_RETURN_NONE;
9825}
9826#endif /* HAVE_LINKAT */
9827
9828#ifdef HAVE_MKDIRAT
9829PyDoc_STRVAR(posix_mkdirat__doc__,
9830"mkdirat(dirfd, path, mode=0o777)\n\n\
9831Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9832If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9833is interpreted relative to the current working directory.");
9834
9835static PyObject *
9836posix_mkdirat(PyObject *self, PyObject *args)
9837{
9838 int res, dirfd;
9839 PyObject *opath;
9840 char *path;
9841 int mode = 0777;
9842
9843 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9844 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9845 return NULL;
9846 path = PyBytes_AsString(opath);
9847 Py_BEGIN_ALLOW_THREADS
9848 res = mkdirat(dirfd, path, mode);
9849 Py_END_ALLOW_THREADS
9850 Py_DECREF(opath);
9851 if (res < 0)
9852 return posix_error();
9853 Py_RETURN_NONE;
9854}
9855#endif
9856
9857#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9858PyDoc_STRVAR(posix_mknodat__doc__,
9859"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9860Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9861If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9862is interpreted relative to the current working directory.");
9863
9864static PyObject *
9865posix_mknodat(PyObject *self, PyObject *args)
9866{
9867 PyObject *opath;
9868 char *filename;
9869 int mode = 0600;
9870 int device = 0;
9871 int res, dirfd;
9872 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9873 PyUnicode_FSConverter, &opath, &mode, &device))
9874 return NULL;
9875 filename = PyBytes_AS_STRING(opath);
9876 Py_BEGIN_ALLOW_THREADS
9877 res = mknodat(dirfd, filename, mode, device);
9878 Py_END_ALLOW_THREADS
9879 Py_DECREF(opath);
9880 if (res < 0)
9881 return posix_error();
9882 Py_RETURN_NONE;
9883}
9884#endif
9885
9886#ifdef HAVE_OPENAT
9887PyDoc_STRVAR(posix_openat__doc__,
9888"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9889Like open() but if path is relative, it is taken as relative to dirfd.\n\
9890If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9891is interpreted relative to the current working directory.");
9892
9893static PyObject *
9894posix_openat(PyObject *self, PyObject *args)
9895{
9896 PyObject *ofile;
9897 char *file;
9898 int flag, dirfd, fd;
9899 int mode = 0777;
9900
9901 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9902 &dirfd, PyUnicode_FSConverter, &ofile,
9903 &flag, &mode))
9904 return NULL;
9905 file = PyBytes_AsString(ofile);
9906 Py_BEGIN_ALLOW_THREADS
9907 fd = openat(dirfd, file, flag, mode);
9908 Py_END_ALLOW_THREADS
9909 Py_DECREF(ofile);
9910 if (fd < 0)
9911 return posix_error();
9912 return PyLong_FromLong((long)fd);
9913}
9914#endif
9915
9916#ifdef HAVE_READLINKAT
9917PyDoc_STRVAR(posix_readlinkat__doc__,
9918"readlinkat(dirfd, path) -> path\n\n\
9919Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9920If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9921is interpreted relative to the current working directory.");
9922
9923static PyObject *
9924posix_readlinkat(PyObject *self, PyObject *args)
9925{
9926 PyObject *v, *opath;
9927 char buf[MAXPATHLEN];
9928 char *path;
9929 int n, dirfd;
9930 int arg_is_unicode = 0;
9931
9932 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9933 &dirfd, PyUnicode_FSConverter, &opath))
9934 return NULL;
9935 path = PyBytes_AsString(opath);
9936 v = PySequence_GetItem(args, 1);
9937 if (v == NULL) {
9938 Py_DECREF(opath);
9939 return NULL;
9940 }
9941
9942 if (PyUnicode_Check(v)) {
9943 arg_is_unicode = 1;
9944 }
9945 Py_DECREF(v);
9946
9947 Py_BEGIN_ALLOW_THREADS
9948 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9949 Py_END_ALLOW_THREADS
9950 Py_DECREF(opath);
9951 if (n < 0)
9952 return posix_error();
9953
9954 if (arg_is_unicode)
9955 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9956 else
9957 return PyBytes_FromStringAndSize(buf, n);
9958}
9959#endif /* HAVE_READLINKAT */
9960
9961#ifdef HAVE_RENAMEAT
9962PyDoc_STRVAR(posix_renameat__doc__,
9963"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9964Like rename() but if oldpath is relative, it is taken as relative to\n\
9965olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9966If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9967oldpath is interpreted relative to the current working directory. This\n\
9968also applies for newpath.");
9969
9970static PyObject *
9971posix_renameat(PyObject *self, PyObject *args)
9972{
9973 int res;
9974 PyObject *opathold, *opathnew;
9975 char *opath, *npath;
9976 int oldfd, newfd;
9977
9978 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9979 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9980 return NULL;
9981 opath = PyBytes_AsString(opathold);
9982 npath = PyBytes_AsString(opathnew);
9983 Py_BEGIN_ALLOW_THREADS
9984 res = renameat(oldfd, opath, newfd, npath);
9985 Py_END_ALLOW_THREADS
9986 Py_DECREF(opathold);
9987 Py_DECREF(opathnew);
9988 if (res < 0)
9989 return posix_error();
9990 Py_RETURN_NONE;
9991}
9992#endif
9993
9994#if HAVE_SYMLINKAT
9995PyDoc_STRVAR(posix_symlinkat__doc__,
9996"symlinkat(src, dstfd, dst)\n\n\
9997Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
9998If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
9999is interpreted relative to the current working directory.");
10000
10001static PyObject *
10002posix_symlinkat(PyObject *self, PyObject *args)
10003{
10004 int res, dstfd;
10005 PyObject *osrc, *odst;
10006 char *src, *dst;
10007
10008 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
10009 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
10010 return NULL;
10011 src = PyBytes_AsString(osrc);
10012 dst = PyBytes_AsString(odst);
10013 Py_BEGIN_ALLOW_THREADS
10014 res = symlinkat(src, dstfd, dst);
10015 Py_END_ALLOW_THREADS
10016 Py_DECREF(osrc);
10017 Py_DECREF(odst);
10018 if (res < 0)
10019 return posix_error();
10020 Py_RETURN_NONE;
10021}
10022#endif /* HAVE_SYMLINKAT */
10023
10024#ifdef HAVE_UNLINKAT
10025PyDoc_STRVAR(posix_unlinkat__doc__,
10026"unlinkat(dirfd, path, flags=0)\n\n\
10027Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
10028flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
10029specified, unlinkat() behaves like rmdir().\n\
10030If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10031is interpreted relative to the current working directory.");
10032
10033static PyObject *
10034posix_unlinkat(PyObject *self, PyObject *args)
10035{
10036 int dirfd, res, flags = 0;
10037 PyObject *opath;
10038 char *path;
10039
10040 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
10041 &dirfd, PyUnicode_FSConverter, &opath, &flags))
10042 return NULL;
10043 path = PyBytes_AsString(opath);
10044 Py_BEGIN_ALLOW_THREADS
10045 res = unlinkat(dirfd, path, flags);
10046 Py_END_ALLOW_THREADS
10047 Py_DECREF(opath);
10048 if (res < 0)
10049 return posix_error();
10050 Py_RETURN_NONE;
10051}
10052#endif
10053
10054#ifdef HAVE_UTIMENSAT
10055PyDoc_STRVAR(posix_utimensat__doc__,
Brian Curtin569b4942011-11-07 16:09:20 -060010056"utimensat(dirfd, path[, atime=(atime_sec, atime_nsec),\n\
10057 mtime=(mtime_sec, mtime_nsec), flags=0])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010058utimensat(dirfd, path, None, None, flags)\n\n\
10059Updates the timestamps of a file with nanosecond precision. If path is\n\
10060relative, it is taken as relative to dirfd.\n\
Brian Curtin569b4942011-11-07 16:09:20 -060010061If atime and mtime are both None, which is the default, set atime and\n\
10062mtime to the current time.\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010063flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
10064If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10065is interpreted relative to the current working directory.\n\
10066If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
10067current time.\n\
10068If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
10069
10070static PyObject *
Brian Curtin569b4942011-11-07 16:09:20 -060010071posix_utimensat(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010072{
10073 PyObject *opath;
10074 char *path;
10075 int res, dirfd, flags = 0;
Brian Curtin569b4942011-11-07 16:09:20 -060010076 PyObject *atime = Py_None;
10077 PyObject *mtime = Py_None;
10078
10079 static char *kwlist[] = {"dirfd", "path", "atime", "mtime", "flags", NULL};
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010080
10081 struct timespec buf[2];
10082
Brian Curtin569b4942011-11-07 16:09:20 -060010083 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|OOi:utimensat", kwlist,
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010084 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
10085 return NULL;
10086 path = PyBytes_AsString(opath);
10087 if (atime == Py_None && mtime == Py_None) {
10088 /* optional time values not given */
10089 Py_BEGIN_ALLOW_THREADS
10090 res = utimensat(dirfd, path, NULL, flags);
10091 Py_END_ALLOW_THREADS
10092 }
10093 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
10094 PyErr_SetString(PyExc_TypeError,
10095 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
10096 Py_DECREF(opath);
10097 return NULL;
10098 }
10099 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
10100 PyErr_SetString(PyExc_TypeError,
10101 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
10102 Py_DECREF(opath);
10103 return NULL;
10104 }
10105 else {
10106 if (!PyArg_ParseTuple(atime, "ll:utimensat",
10107 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
10108 Py_DECREF(opath);
10109 return NULL;
10110 }
10111 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
10112 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
10113 Py_DECREF(opath);
10114 return NULL;
10115 }
10116 Py_BEGIN_ALLOW_THREADS
10117 res = utimensat(dirfd, path, buf, flags);
10118 Py_END_ALLOW_THREADS
10119 }
10120 Py_DECREF(opath);
10121 if (res < 0) {
10122 return posix_error();
10123 }
10124 Py_RETURN_NONE;
10125}
10126#endif
10127
10128#ifdef HAVE_MKFIFOAT
10129PyDoc_STRVAR(posix_mkfifoat__doc__,
10130"mkfifoat(dirfd, path, mode=0o666)\n\n\
10131Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
10132If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10133is interpreted relative to the current working directory.");
10134
10135static PyObject *
10136posix_mkfifoat(PyObject *self, PyObject *args)
10137{
10138 PyObject *opath;
10139 char *filename;
10140 int mode = 0666;
10141 int res, dirfd;
10142 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
10143 &dirfd, PyUnicode_FSConverter, &opath, &mode))
10144 return NULL;
10145 filename = PyBytes_AS_STRING(opath);
10146 Py_BEGIN_ALLOW_THREADS
10147 res = mkfifoat(dirfd, filename, mode);
10148 Py_END_ALLOW_THREADS
10149 Py_DECREF(opath);
10150 if (res < 0)
10151 return posix_error();
10152 Py_RETURN_NONE;
10153}
10154#endif
10155
Benjamin Peterson9428d532011-09-14 11:45:52 -040010156#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010157
10158static int
10159try_getxattr(const char *path, const char *name,
10160 ssize_t (*get)(const char *, const char *, void *, size_t),
10161 Py_ssize_t buf_size, PyObject **res)
10162{
10163 PyObject *value;
10164 Py_ssize_t len;
10165
10166 assert(buf_size <= XATTR_SIZE_MAX);
10167 value = PyBytes_FromStringAndSize(NULL, buf_size);
10168 if (!value)
10169 return 0;
10170 Py_BEGIN_ALLOW_THREADS;
10171 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10172 Py_END_ALLOW_THREADS;
10173 if (len < 0) {
10174 Py_DECREF(value);
10175 if (errno == ERANGE) {
10176 value = NULL;
10177 }
10178 else {
10179 posix_error();
10180 return 0;
10181 }
10182 }
10183 else if (len != buf_size) {
10184 /* Can only shrink. */
10185 _PyBytes_Resize(&value, len);
10186 }
10187 *res = value;
10188 return 1;
10189}
10190
10191static PyObject *
10192getxattr_common(const char *path, PyObject *name_obj,
10193 ssize_t (*get)(const char *, const char *, void *, size_t))
10194{
10195 PyObject *value;
10196 const char *name = PyBytes_AS_STRING(name_obj);
10197
10198 /* Try a small value first. */
10199 if (!try_getxattr(path, name, get, 128, &value))
10200 return NULL;
10201 if (value)
10202 return value;
10203 /* Now the maximum possible one. */
10204 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10205 return NULL;
10206 assert(value);
10207 return value;
10208}
10209
10210PyDoc_STRVAR(posix_getxattr__doc__,
10211"getxattr(path, attr) -> value\n\n\
10212Return the value of extended attribute *name* on *path*.");
10213
10214static PyObject *
10215posix_getxattr(PyObject *self, PyObject *args)
10216{
10217 PyObject *path, *res, *name;
10218
10219 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10220 PyUnicode_FSConverter, &name))
10221 return NULL;
10222 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10223 Py_DECREF(path);
10224 Py_DECREF(name);
10225 return res;
10226}
10227
10228PyDoc_STRVAR(posix_lgetxattr__doc__,
10229"lgetxattr(path, attr) -> value\n\n\
10230Like getxattr but don't follow symlinks.");
10231
10232static PyObject *
10233posix_lgetxattr(PyObject *self, PyObject *args)
10234{
10235 PyObject *path, *res, *name;
10236
10237 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10238 PyUnicode_FSConverter, &name))
10239 return NULL;
10240 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10241 Py_DECREF(path);
10242 Py_DECREF(name);
10243 return res;
10244}
10245
10246static ssize_t
10247wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10248{
10249 /* Hack to share code. */
10250 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10251}
10252
10253PyDoc_STRVAR(posix_fgetxattr__doc__,
10254"fgetxattr(fd, attr) -> value\n\n\
10255Like getxattr but operate on a fd instead of a path.");
10256
10257static PyObject *
10258posix_fgetxattr(PyObject *self, PyObject *args)
10259{
10260 PyObject *res, *name;
10261 int fd;
10262
10263 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10264 return NULL;
10265 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10266 Py_DECREF(name);
10267 return res;
10268}
10269
10270PyDoc_STRVAR(posix_setxattr__doc__,
10271"setxattr(path, attr, value, flags=0)\n\n\
10272Set extended attribute *attr* on *path* to *value*.");
10273
10274static PyObject *
10275posix_setxattr(PyObject *self, PyObject *args)
10276{
10277 PyObject *path, *name;
10278 Py_buffer data;
10279 int flags = 0, err;
10280
10281 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10282 &path, PyUnicode_FSConverter, &name, &data, &flags))
10283 return NULL;
10284 Py_BEGIN_ALLOW_THREADS;
10285 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10286 data.buf, data.len, flags);
10287 Py_END_ALLOW_THREADS;
10288 Py_DECREF(path);
10289 Py_DECREF(name);
10290 PyBuffer_Release(&data);
10291 if (err)
10292 return posix_error();
10293 Py_RETURN_NONE;
10294}
10295
10296PyDoc_STRVAR(posix_lsetxattr__doc__,
10297"lsetxattr(path, attr, value, flags=0)\n\n\
10298Like setxattr but don't follow symlinks.");
10299
10300static PyObject *
10301posix_lsetxattr(PyObject *self, PyObject *args)
10302{
10303 PyObject *path, *name;
10304 Py_buffer data;
10305 int flags = 0, err;
10306
10307 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10308 &path, PyUnicode_FSConverter, &name, &data, &flags))
10309 return NULL;
10310 Py_BEGIN_ALLOW_THREADS;
10311 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10312 data.buf, data.len, flags);
10313 Py_END_ALLOW_THREADS;
10314 Py_DECREF(path);
10315 Py_DECREF(name);
10316 PyBuffer_Release(&data);
10317 if (err)
10318 return posix_error();
10319 Py_RETURN_NONE;
10320}
10321
10322PyDoc_STRVAR(posix_fsetxattr__doc__,
10323"fsetxattr(fd, attr, value, flags=0)\n\n\
10324Like setxattr but operates on *fd* instead of a path.");
10325
10326static PyObject *
10327posix_fsetxattr(PyObject *self, PyObject *args)
10328{
10329 Py_buffer data;
10330 const char *name;
10331 int fd, flags = 0, err;
10332
10333 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10334 &name, &data, &flags))
10335 return NULL;
10336 Py_BEGIN_ALLOW_THREADS;
10337 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10338 Py_END_ALLOW_THREADS;
10339 Py_DECREF(name);
10340 PyBuffer_Release(&data);
10341 if (err)
10342 return posix_error();
10343 Py_RETURN_NONE;
10344}
10345
10346PyDoc_STRVAR(posix_removexattr__doc__,
10347"removexattr(path, attr)\n\n\
10348Remove extended attribute *attr* on *path*.");
10349
10350static PyObject *
10351posix_removexattr(PyObject *self, PyObject *args)
10352{
10353 PyObject *path, *name;
10354 int err;
10355
10356 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10357 PyUnicode_FSConverter, &name))
10358 return NULL;
10359 Py_BEGIN_ALLOW_THREADS;
10360 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10361 Py_END_ALLOW_THREADS;
10362 Py_DECREF(path);
10363 Py_DECREF(name);
10364 if (err)
10365 return posix_error();
10366 Py_RETURN_NONE;
10367}
10368
10369PyDoc_STRVAR(posix_lremovexattr__doc__,
10370"lremovexattr(path, attr)\n\n\
10371Like removexattr but don't follow symlinks.");
10372
10373static PyObject *
10374posix_lremovexattr(PyObject *self, PyObject *args)
10375{
10376 PyObject *path, *name;
10377 int err;
10378
10379 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10380 PyUnicode_FSConverter, &name))
10381 return NULL;
10382 Py_BEGIN_ALLOW_THREADS;
10383 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10384 Py_END_ALLOW_THREADS;
10385 Py_DECREF(path);
10386 Py_DECREF(name);
10387 if (err)
10388 return posix_error();
10389 Py_RETURN_NONE;
10390}
10391
10392PyDoc_STRVAR(posix_fremovexattr__doc__,
10393"fremovexattr(fd, attr)\n\n\
10394Like removexattr but operates on a file descriptor.");
10395
10396static PyObject *
10397posix_fremovexattr(PyObject *self, PyObject *args)
10398{
10399 PyObject *name;
10400 int fd, err;
10401
10402 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10403 PyUnicode_FSConverter, &name))
10404 return NULL;
10405 Py_BEGIN_ALLOW_THREADS;
10406 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10407 Py_END_ALLOW_THREADS;
10408 Py_DECREF(name);
10409 if (err)
10410 return posix_error();
10411 Py_RETURN_NONE;
10412}
10413
10414static Py_ssize_t
10415try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10416 Py_ssize_t buf_size, char **buf)
10417{
10418 Py_ssize_t len;
10419
10420 *buf = PyMem_MALLOC(buf_size);
10421 if (!*buf) {
10422 PyErr_NoMemory();
10423 return -1;
10424 }
10425 Py_BEGIN_ALLOW_THREADS;
10426 len = list(path, *buf, buf_size);
10427 Py_END_ALLOW_THREADS;
10428 if (len < 0) {
10429 PyMem_FREE(*buf);
10430 if (errno != ERANGE)
10431 posix_error();
10432 return -1;
10433 }
10434 return len;
10435}
10436
10437static PyObject *
10438listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10439{
10440 PyObject *res, *attr;
10441 Py_ssize_t len, err, start, i;
10442 char *buf;
10443
10444 len = try_listxattr(path, list, 256, &buf);
10445 if (len < 0) {
10446 if (PyErr_Occurred())
10447 return NULL;
10448 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10449 if (len < 0)
10450 return NULL;
10451 }
10452 res = PyList_New(0);
10453 if (!res) {
10454 PyMem_FREE(buf);
10455 return NULL;
10456 }
10457 for (start = i = 0; i < len; i++) {
10458 if (!buf[i]) {
10459 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10460 if (!attr) {
10461 Py_DECREF(res);
10462 PyMem_FREE(buf);
10463 return NULL;
10464 }
10465 err = PyList_Append(res, attr);
10466 Py_DECREF(attr);
10467 if (err) {
10468 Py_DECREF(res);
10469 PyMem_FREE(buf);
10470 return NULL;
10471 }
10472 start = i + 1;
10473 }
10474 }
10475 PyMem_FREE(buf);
10476 return res;
10477}
10478
10479PyDoc_STRVAR(posix_listxattr__doc__,
10480"listxattr(path)\n\n\
10481Return a list of extended attributes on *path*.");
10482
10483static PyObject *
10484posix_listxattr(PyObject *self, PyObject *args)
10485{
10486 PyObject *path, *res;
10487
10488 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10489 return NULL;
10490 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10491 Py_DECREF(path);
10492 return res;
10493}
10494
10495PyDoc_STRVAR(posix_llistxattr__doc__,
10496"llistxattr(path)\n\n\
10497Like listxattr but don't follow symlinks..");
10498
10499static PyObject *
10500posix_llistxattr(PyObject *self, PyObject *args)
10501{
10502 PyObject *path, *res;
10503
10504 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10505 return NULL;
10506 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10507 Py_DECREF(path);
10508 return res;
10509}
10510
10511static ssize_t
10512wrap_flistxattr(const char *path, char *buf, size_t len)
10513{
10514 /* Hack to share code. */
10515 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10516}
10517
10518PyDoc_STRVAR(posix_flistxattr__doc__,
10519"flistxattr(path)\n\n\
10520Like flistxattr but operates on a file descriptor.");
10521
10522static PyObject *
10523posix_flistxattr(PyObject *self, PyObject *args)
10524{
10525 long fd;
10526
10527 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10528 return NULL;
10529 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10530}
10531
Benjamin Peterson9428d532011-09-14 11:45:52 -040010532#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010533
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010534static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +000010535 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010536#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010537 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010538#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010540#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010542#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010544#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010546#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010547#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010548 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010549#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010550#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010551 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010552#endif /* HAVE_LCHMOD */
10553#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010554 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010555#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010556#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010558#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010559#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010560 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010561#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010562#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010563 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010564#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010565#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010566 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010567#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +000010568#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010569 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10570 METH_NOARGS, posix_getcwd__doc__},
10571 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10572 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +000010573#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010574#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010575 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010576#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010577 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010578#ifdef HAVE_FDOPENDIR
10579 {"fdlistdir", posix_fdlistdir, METH_VARARGS, posix_fdlistdir__doc__},
10580#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
10582 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010583#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010585#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010586#ifdef HAVE_GETPRIORITY
10587 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10588#endif /* HAVE_GETPRIORITY */
10589#ifdef HAVE_SETPRIORITY
10590 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10591#endif /* HAVE_SETPRIORITY */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010592#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010593 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010594#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010595#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010596 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010597#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010598 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
10599 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
10600 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010602#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010604#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010605#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010606 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010607 win_symlink__doc__},
10608#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010609#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010610 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010611#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010612 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010613#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010614 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010615#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10617 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
10618 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010619#ifdef HAVE_FUTIMES
10620 {"futimes", posix_futimes, METH_VARARGS, posix_futimes__doc__},
10621#endif
10622#ifdef HAVE_LUTIMES
10623 {"lutimes", posix_lutimes, METH_VARARGS, posix_lutimes__doc__},
10624#endif
10625#ifdef HAVE_FUTIMENS
10626 {"futimens", posix_futimens, METH_VARARGS, posix_futimens__doc__},
10627#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010628#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010629 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010630#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010632#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10634 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010635#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010636#ifdef HAVE_FEXECVE
10637 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10638#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010639#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10641 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010642#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10644 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010645#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010646#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010647#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010649#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010650#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010652#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010653#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010654#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010655 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10656 {"sched_get_priority_min", posix_sched_get_priority_min, METH_VARARGS, posix_sched_get_priority_min__doc__},
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010657#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010658#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010659 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010660#endif
10661#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010662 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010663#endif
10664#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010665 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010666#endif
10667#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010668 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010669#endif
10670#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010671 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010672#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010673 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010674#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010675 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10676 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10677#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010678#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010679#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010680 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010681#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010682#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010683 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010684#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010685#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010686 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010687#endif /* HAVE_GETEGID */
10688#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010689 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010690#endif /* HAVE_GETEUID */
10691#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010692 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010693#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010694#ifdef HAVE_GETGROUPLIST
10695 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10696#endif
Fred Drakec9680921999-12-13 16:37:25 +000010697#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010699#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010700 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010701#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010702 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010703#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010704#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010705 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010706#endif /* HAVE_GETPPID */
10707#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010709#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010710#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010712#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010713#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010715#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010716#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010718#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010719#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010721#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010722#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10724 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010725 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010726#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010727#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010728 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010729#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010730#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010731 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010732#endif /* HAVE_SETEUID */
10733#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010735#endif /* HAVE_SETEGID */
10736#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010738#endif /* HAVE_SETREUID */
10739#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010741#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010742#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010744#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010745#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010747#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010748#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010750#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010751#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010753#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010754#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010755 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010756#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010757#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010759#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010760#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010762#endif /* HAVE_WAIT3 */
10763#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010765#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010766#if defined(HAVE_WAITID) && !defined(__APPLE__)
10767 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10768#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010769#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010771#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010772#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010773 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010774#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010775#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010776 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010777#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010778#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010780#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010781#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010783#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010784#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010786#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10788 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10789 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10790 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10791 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10792 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010793#ifdef HAVE_LOCKF
10794 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10795#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010796 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10797 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010798#ifdef HAVE_READV
10799 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10800#endif
10801#ifdef HAVE_PREAD
10802 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10803#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010805#ifdef HAVE_WRITEV
10806 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10807#endif
10808#ifdef HAVE_PWRITE
10809 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10810#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010811#ifdef HAVE_SENDFILE
10812 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10813 posix_sendfile__doc__},
10814#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010815 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
10816 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010817#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010818 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010819#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010820#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010821 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010822#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010823#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010824 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010825#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010826#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010828#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010829#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10831 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10832 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010833#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010834#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010835 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010836#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010837#ifdef HAVE_TRUNCATE
10838 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10839#endif
10840#ifdef HAVE_POSIX_FALLOCATE
10841 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10842#endif
10843#ifdef HAVE_POSIX_FADVISE
10844 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10845#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010846#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010847 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010848#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010849#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010850 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010851#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010853#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010854 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010855#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010856#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010857 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010858#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010859#ifdef HAVE_SYNC
10860 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10861#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010862#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010864#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010865#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010866#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010867 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010868#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010869#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010870 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010871#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010872#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010873 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010874#endif /* WIFSTOPPED */
10875#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010877#endif /* WIFSIGNALED */
10878#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010880#endif /* WIFEXITED */
10881#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010883#endif /* WEXITSTATUS */
10884#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010886#endif /* WTERMSIG */
10887#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010889#endif /* WSTOPSIG */
10890#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010891#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010892 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010893#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010894#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010895 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010896#endif
Fred Drakec9680921999-12-13 16:37:25 +000010897#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010898 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010899#endif
10900#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010902#endif
10903#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010905#endif
10906#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010908#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010909 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010910#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010911 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010912 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010913 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010914 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010915 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010916#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010917#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010919#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010920 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010921 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010922 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010923 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +000010924 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010925 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010926#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010928#endif
10929#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010931#endif
10932#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010934#endif
10935#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010937#endif
10938
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010939/* posix *at family of functions */
10940#ifdef HAVE_FACCESSAT
10941 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
10942#endif
10943#ifdef HAVE_FCHMODAT
10944 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
10945#endif /* HAVE_FCHMODAT */
10946#ifdef HAVE_FCHOWNAT
10947 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
10948#endif /* HAVE_FCHOWNAT */
10949#ifdef HAVE_FSTATAT
10950 {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__},
10951#endif
10952#ifdef HAVE_FUTIMESAT
10953 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
10954#endif
10955#ifdef HAVE_LINKAT
10956 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
10957#endif /* HAVE_LINKAT */
10958#ifdef HAVE_MKDIRAT
10959 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
10960#endif
10961#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
10962 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
10963#endif
10964#ifdef HAVE_OPENAT
10965 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
10966#endif
10967#ifdef HAVE_READLINKAT
10968 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
10969#endif /* HAVE_READLINKAT */
10970#ifdef HAVE_RENAMEAT
10971 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
10972#endif
10973#if HAVE_SYMLINKAT
10974 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
10975#endif /* HAVE_SYMLINKAT */
10976#ifdef HAVE_UNLINKAT
10977 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
10978#endif
10979#ifdef HAVE_UTIMENSAT
Jesus Cead03a4912011-11-08 17:28:04 +010010980 {"utimensat", (PyCFunction)posix_utimensat,
10981 METH_VARARGS | METH_KEYWORDS,
Brian Curtin569b4942011-11-07 16:09:20 -060010982 posix_utimensat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010983#endif
10984#ifdef HAVE_MKFIFOAT
10985 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
10986#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040010987#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010988 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
10989 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
10990 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
10991 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
10992 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
10993 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
10994 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
10995 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
10996 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
10997 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
10998 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
10999 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
11000#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011001 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011002};
11003
11004
Barry Warsaw4a342091996-12-19 23:50:02 +000011005static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011006ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011007{
Victor Stinner8c62be82010-05-06 00:08:46 +000011008 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011009}
11010
Guido van Rossumd48f2521997-12-05 22:19:34 +000011011#if defined(PYOS_OS2)
11012/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011013static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011014{
11015 APIRET rc;
11016 ULONG values[QSV_MAX+1];
11017 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011018 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011019
11020 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011021 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011022 Py_END_ALLOW_THREADS
11023
11024 if (rc != NO_ERROR) {
11025 os2_error(rc);
11026 return -1;
11027 }
11028
Fred Drake4d1e64b2002-04-15 19:40:07 +000011029 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11030 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11031 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11032 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11033 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11034 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11035 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011036
11037 switch (values[QSV_VERSION_MINOR]) {
11038 case 0: ver = "2.00"; break;
11039 case 10: ver = "2.10"; break;
11040 case 11: ver = "2.11"; break;
11041 case 30: ver = "3.00"; break;
11042 case 40: ver = "4.00"; break;
11043 case 50: ver = "5.00"; break;
11044 default:
Tim Peters885d4572001-11-28 20:27:42 +000011045 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011046 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011047 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011048 ver = &tmp[0];
11049 }
11050
11051 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011052 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011053 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011054
11055 /* Add Indicator of Which Drive was Used to Boot the System */
11056 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11057 tmp[1] = ':';
11058 tmp[2] = '\0';
11059
Fred Drake4d1e64b2002-04-15 19:40:07 +000011060 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011061}
11062#endif
11063
Brian Curtin52173d42010-12-02 18:29:18 +000011064#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011065static int
Brian Curtin52173d42010-12-02 18:29:18 +000011066enable_symlink()
11067{
11068 HANDLE tok;
11069 TOKEN_PRIVILEGES tok_priv;
11070 LUID luid;
11071 int meth_idx = 0;
11072
11073 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011074 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011075
11076 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011077 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011078
11079 tok_priv.PrivilegeCount = 1;
11080 tok_priv.Privileges[0].Luid = luid;
11081 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11082
11083 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11084 sizeof(TOKEN_PRIVILEGES),
11085 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011086 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011087
Brian Curtin3b4499c2010-12-28 14:31:47 +000011088 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11089 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011090}
11091#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11092
Barry Warsaw4a342091996-12-19 23:50:02 +000011093static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011094all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011095{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011096#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011097 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011098#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011099#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011100 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011101#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011102#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011103 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011104#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011105#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011106 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011107#endif
Fred Drakec9680921999-12-13 16:37:25 +000011108#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011109 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011110#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011111#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011112 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011113#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011114#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011115 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011116#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011117#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011118 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011119#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011120#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011121 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011122#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011123#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011124 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011125#endif
11126#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011127 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011128#endif
11129#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011130 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011131#endif
11132#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011133 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011134#endif
11135#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011136 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011137#endif
11138#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011139 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011140#endif
11141#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011142 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011143#endif
11144#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011145 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011146#endif
11147#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011148 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011149#endif
11150#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011151 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011152#endif
11153#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011154 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011155#endif
11156#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011157 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011158#endif
11159#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011160 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011161#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011162#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011163 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011164#endif
11165#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011166 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011167#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011168#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011169 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011170#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011171#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011172 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011173#endif
11174#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011175 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011176#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011177#ifdef PRIO_PROCESS
11178 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11179#endif
11180#ifdef PRIO_PGRP
11181 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11182#endif
11183#ifdef PRIO_USER
11184 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11185#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011186#ifdef O_CLOEXEC
11187 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11188#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011189/* posix - constants for *at functions */
11190#ifdef AT_SYMLINK_NOFOLLOW
11191 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11192#endif
11193#ifdef AT_EACCESS
11194 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11195#endif
11196#ifdef AT_FDCWD
11197 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11198#endif
11199#ifdef AT_REMOVEDIR
11200 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11201#endif
11202#ifdef AT_SYMLINK_FOLLOW
11203 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11204#endif
11205#ifdef UTIME_NOW
11206 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11207#endif
11208#ifdef UTIME_OMIT
11209 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11210#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011211
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011212
Tim Peters5aa91602002-01-30 05:46:57 +000011213/* MS Windows */
11214#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011215 /* Don't inherit in child processes. */
11216 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011217#endif
11218#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011219 /* Optimize for short life (keep in memory). */
11220 /* MS forgot to define this one with a non-underscore form too. */
11221 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011222#endif
11223#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011224 /* Automatically delete when last handle is closed. */
11225 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011226#endif
11227#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011228 /* Optimize for random access. */
11229 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011230#endif
11231#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011232 /* Optimize for sequential access. */
11233 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011234#endif
11235
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011236/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011237#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 /* Send a SIGIO signal whenever input or output
11239 becomes available on file descriptor */
11240 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011241#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011242#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011243 /* Direct disk access. */
11244 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011245#endif
11246#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011247 /* Must be a directory. */
11248 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011249#endif
11250#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011251 /* Do not follow links. */
11252 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011253#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011254#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011255 /* Do not update the access time. */
11256 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011257#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011258
Victor Stinner8c62be82010-05-06 00:08:46 +000011259 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011260#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011262#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011263#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011264 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011265#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011266#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011267 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011268#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011269#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011270 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011271#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011272#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011273 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011274#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011275#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011276 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011277#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011278#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011279 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011280#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011281#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011282 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011283#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011284#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011285 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011286#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011287#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011288 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011289#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011290#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011291 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011292#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011293#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011294 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011295#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011296#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011297 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011298#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011299#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011300 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011301#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011302#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011303 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011304#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011305#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011306 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011307#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011308#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011309 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011310#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011311
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011312 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011313#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011314 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011315#endif /* ST_RDONLY */
11316#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011317 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011318#endif /* ST_NOSUID */
11319
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011320 /* FreeBSD sendfile() constants */
11321#ifdef SF_NODISKIO
11322 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11323#endif
11324#ifdef SF_MNOWAIT
11325 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11326#endif
11327#ifdef SF_SYNC
11328 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11329#endif
11330
Ross Lagerwall7807c352011-03-17 20:20:30 +020011331 /* constants for posix_fadvise */
11332#ifdef POSIX_FADV_NORMAL
11333 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11334#endif
11335#ifdef POSIX_FADV_SEQUENTIAL
11336 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11337#endif
11338#ifdef POSIX_FADV_RANDOM
11339 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11340#endif
11341#ifdef POSIX_FADV_NOREUSE
11342 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11343#endif
11344#ifdef POSIX_FADV_WILLNEED
11345 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11346#endif
11347#ifdef POSIX_FADV_DONTNEED
11348 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11349#endif
11350
11351 /* constants for waitid */
11352#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11353 if (ins(d, "P_PID", (long)P_PID)) return -1;
11354 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11355 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11356#endif
11357#ifdef WEXITED
11358 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11359#endif
11360#ifdef WNOWAIT
11361 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11362#endif
11363#ifdef WSTOPPED
11364 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11365#endif
11366#ifdef CLD_EXITED
11367 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11368#endif
11369#ifdef CLD_DUMPED
11370 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11371#endif
11372#ifdef CLD_TRAPPED
11373 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11374#endif
11375#ifdef CLD_CONTINUED
11376 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11377#endif
11378
11379 /* constants for lockf */
11380#ifdef F_LOCK
11381 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11382#endif
11383#ifdef F_TLOCK
11384 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11385#endif
11386#ifdef F_ULOCK
11387 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11388#endif
11389#ifdef F_TEST
11390 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11391#endif
11392
11393 /* constants for futimens */
11394#ifdef UTIME_NOW
11395 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11396#endif
11397#ifdef UTIME_OMIT
11398 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11399#endif
11400
Guido van Rossum246bc171999-02-01 23:54:31 +000011401#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011402#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011403 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11404 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11405 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11406 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11407 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11408 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11409 if (ins(d, "P_PM", (long)P_PM)) return -1;
11410 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11411 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11412 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11413 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11414 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11415 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11416 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11417 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11418 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11419 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11420 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11421 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11422 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011423#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011424 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11425 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11426 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11427 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11428 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011429#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011430#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011431
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011432#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011433 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011434 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11435 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11436#ifdef SCHED_SPORADIC
11437 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11438#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011439#ifdef SCHED_BATCH
11440 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11441#endif
11442#ifdef SCHED_IDLE
11443 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11444#endif
11445#ifdef SCHED_RESET_ON_FORK
11446 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11447#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011448#ifdef SCHED_SYS
11449 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11450#endif
11451#ifdef SCHED_IA
11452 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11453#endif
11454#ifdef SCHED_FSS
11455 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11456#endif
11457#ifdef SCHED_FX
11458 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11459#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011460#endif
11461
Benjamin Peterson9428d532011-09-14 11:45:52 -040011462#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011463 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11464 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11465 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11466#endif
11467
Victor Stinner8b905bd2011-10-25 13:34:04 +020011468#ifdef RTLD_LAZY
11469 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11470#endif
11471#ifdef RTLD_NOW
11472 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11473#endif
11474#ifdef RTLD_GLOBAL
11475 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11476#endif
11477#ifdef RTLD_LOCAL
11478 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11479#endif
11480#ifdef RTLD_NODELETE
11481 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11482#endif
11483#ifdef RTLD_NOLOAD
11484 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11485#endif
11486#ifdef RTLD_DEEPBIND
11487 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11488#endif
11489
Guido van Rossumd48f2521997-12-05 22:19:34 +000011490#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011491 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011492#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011493 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011494}
11495
11496
Tim Peters5aa91602002-01-30 05:46:57 +000011497#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011498#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011499#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011500
11501#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011502#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011503#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011504
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011505#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011506#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011507#define MODNAME "posix"
11508#endif
11509
Martin v. Löwis1a214512008-06-11 05:26:20 +000011510static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011511 PyModuleDef_HEAD_INIT,
11512 MODNAME,
11513 posix__doc__,
11514 -1,
11515 posix_methods,
11516 NULL,
11517 NULL,
11518 NULL,
11519 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011520};
11521
11522
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011523PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011524INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011525{
Victor Stinner8c62be82010-05-06 00:08:46 +000011526 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011527
Brian Curtin52173d42010-12-02 18:29:18 +000011528#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011529 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011530#endif
11531
Victor Stinner8c62be82010-05-06 00:08:46 +000011532 m = PyModule_Create(&posixmodule);
11533 if (m == NULL)
11534 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011535
Victor Stinner8c62be82010-05-06 00:08:46 +000011536 /* Initialize environ dictionary */
11537 v = convertenviron();
11538 Py_XINCREF(v);
11539 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11540 return NULL;
11541 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011542
Victor Stinner8c62be82010-05-06 00:08:46 +000011543 if (all_ins(m))
11544 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011545
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 if (setup_confname_tables(m))
11547 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011548
Victor Stinner8c62be82010-05-06 00:08:46 +000011549 Py_INCREF(PyExc_OSError);
11550 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011551
Benjamin Peterson2740af82011-08-02 17:41:34 -050011552#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011553 if (PyType_Ready(&cpu_set_type) < 0)
11554 return NULL;
11555 Py_INCREF(&cpu_set_type);
11556 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011557#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011558
Guido van Rossumb3d39562000-01-31 18:41:26 +000011559#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011560 if (posix_putenv_garbage == NULL)
11561 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011562#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011563
Victor Stinner8c62be82010-05-06 00:08:46 +000011564 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011565#if defined(HAVE_WAITID) && !defined(__APPLE__)
11566 waitid_result_desc.name = MODNAME ".waitid_result";
11567 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11568#endif
11569
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 stat_result_desc.name = MODNAME ".stat_result";
11571 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11572 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11573 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11574 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11575 structseq_new = StatResultType.tp_new;
11576 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011577
Victor Stinner8c62be82010-05-06 00:08:46 +000011578 statvfs_result_desc.name = MODNAME ".statvfs_result";
11579 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011580#ifdef NEED_TICKS_PER_SECOND
11581# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011582 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011583# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011584 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011585# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011586 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011587# endif
11588#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011589
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011590#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011591 sched_param_desc.name = MODNAME ".sched_param";
11592 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11593 SchedParamType.tp_new = sched_param_new;
11594#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011595 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011596#if defined(HAVE_WAITID) && !defined(__APPLE__)
11597 Py_INCREF((PyObject*) &WaitidResultType);
11598 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11599#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011600 Py_INCREF((PyObject*) &StatResultType);
11601 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11602 Py_INCREF((PyObject*) &StatVFSResultType);
11603 PyModule_AddObject(m, "statvfs_result",
11604 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011605
11606#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011607 Py_INCREF(&SchedParamType);
11608 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011609#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011611
11612#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011613 /*
11614 * Step 2 of weak-linking support on Mac OS X.
11615 *
11616 * The code below removes functions that are not available on the
11617 * currently active platform.
11618 *
11619 * This block allow one to use a python binary that was build on
11620 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11621 * OSX 10.4.
11622 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011623#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011624 if (fstatvfs == NULL) {
11625 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11626 return NULL;
11627 }
11628 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011629#endif /* HAVE_FSTATVFS */
11630
11631#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011632 if (statvfs == NULL) {
11633 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11634 return NULL;
11635 }
11636 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011637#endif /* HAVE_STATVFS */
11638
11639# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011640 if (lchown == NULL) {
11641 if (PyObject_DelAttrString(m, "lchown") == -1) {
11642 return NULL;
11643 }
11644 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011645#endif /* HAVE_LCHOWN */
11646
11647
11648#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +000011649 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011650
Guido van Rossumb6775db1994-08-01 11:34:53 +000011651}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011652
11653#ifdef __cplusplus
11654}
11655#endif