blob: 0ab63c305a00a769183cc881cd5d406c2864389e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Thomas Wouters477c8d52006-05-27 19:21:47 +000014#ifdef __APPLE__
15 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000030#if defined(__VMS)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020031# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4"
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#if defined(PYOS_OS2)
Victor Stinnerb90db4c2011-04-26 22:48:24 +020047#error "PEP 11: OS/2 is now unsupported, code will be removed in Python 3.4"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#define INCL_DOS
49#define INCL_DOSERRORS
50#define INCL_DOSPROCESS
51#define INCL_NOPMAPI
52#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000053#if defined(PYCC_GCC)
54#include <ctype.h>
55#include <io.h>
56#include <stdio.h>
57#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000059#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000060#endif
61
Ross Lagerwall4d076da2011-03-18 06:56:53 +020062#ifdef HAVE_SYS_UIO_H
63#include <sys/uio.h>
64#endif
65
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068#endif /* HAVE_SYS_TYPES_H */
69
70#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000073
Guido van Rossum36bc6801995-06-14 22:54:23 +000074#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000075#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Thomas Wouters0e3f5912006-08-11 14:57:12 +000078#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000079#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000080#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000081
Guido van Rossumb6775db1994-08-01 11:34:53 +000082#ifdef HAVE_FCNTL_H
83#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000084#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossuma6535fd2001-10-18 19:44:10 +000086#ifdef HAVE_GRP_H
87#include <grp.h>
88#endif
89
Barry Warsaw5676bd12003-01-07 20:57:09 +000090#ifdef HAVE_SYSEXITS_H
91#include <sysexits.h>
92#endif /* HAVE_SYSEXITS_H */
93
Anthony Baxter8a560de2004-10-13 15:30:56 +000094#ifdef HAVE_SYS_LOADAVG_H
95#include <sys/loadavg.h>
96#endif
97
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000098#ifdef HAVE_LANGINFO_H
99#include <langinfo.h>
100#endif
101
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000102#ifdef HAVE_SYS_SENDFILE_H
103#include <sys/sendfile.h>
104#endif
105
Benjamin Peterson94b580d2011-08-02 17:30:04 -0500106#ifdef HAVE_SCHED_H
107#include <sched.h>
108#endif
109
Benjamin Peterson9428d532011-09-14 11:45:52 -0400110#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__)
111#define USE_XATTRS
112#endif
113
114#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400115#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400116#endif
117
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
119#ifdef HAVE_SYS_SOCKET_H
120#include <sys/socket.h>
121#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000122#endif
123
Victor Stinner8b905bd2011-10-25 13:34:04 +0200124#ifdef HAVE_DLFCN_H
125#include <dlfcn.h>
126#endif
127
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000129/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000131#include <process.h>
132#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000133#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#define HAVE_GETCWD 1
135#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#if defined(__OS2__)
138#define HAVE_EXECV 1
139#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#include <process.h>
142#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000143#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#define HAVE_EXECV 1
145#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_OPENDIR 1
147#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000148#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_WAIT 1
150#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000152#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000153#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000154#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#define HAVE_EXECV 1
157#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#define HAVE_SYSTEM 1
159#define HAVE_CWAIT 1
160#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000161#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000162#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000163#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
164/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166/* Unix functions that the configure script doesn't check for */
167#define HAVE_EXECV 1
168#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000170#define HAVE_FORK1 1
171#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_GETCWD 1
173#define HAVE_GETEGID 1
174#define HAVE_GETEUID 1
175#define HAVE_GETGID 1
176#define HAVE_GETPPID 1
177#define HAVE_GETUID 1
178#define HAVE_KILL 1
179#define HAVE_OPENDIR 1
180#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000181#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000182#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000183#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000184#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#endif /* _MSC_VER */
186#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000187#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000189
Victor Stinnera2f7c002012-02-08 03:36:25 +0100190
191
192
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000193#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000194
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000195#if defined(__sgi)&&_COMPILER_VERSION>=700
196/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
197 (default) */
198extern char *ctermid_r(char *);
199#endif
200
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000201#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000205#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#endif
211#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chdir(char *);
213extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000214#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int chdir(const char *);
216extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000217#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000218#ifdef __BORLANDC__
219extern int chmod(const char *, int);
220#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000222#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000223/*#ifdef HAVE_FCHMOD
224extern int fchmod(int, mode_t);
225#endif*/
226/*#ifdef HAVE_LCHMOD
227extern int lchmod(const char *, mode_t);
228#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000229extern int chown(const char *, uid_t, gid_t);
230extern char *getcwd(char *, int);
231extern char *strerror(int);
232extern int link(const char *, const char *);
233extern int rename(const char *, const char *);
234extern int stat(const char *, struct stat *);
235extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000237extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000238#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000240extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000241#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000243
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#ifdef HAVE_UTIME_H
247#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000248#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000250#ifdef HAVE_SYS_UTIME_H
251#include <sys/utime.h>
252#define HAVE_UTIME_H /* pretend we do for the rest of this file */
253#endif /* HAVE_SYS_UTIME_H */
254
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#ifdef HAVE_SYS_TIMES_H
256#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_PARAM_H
260#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
263#ifdef HAVE_SYS_UTSNAME_H
264#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000265#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000267#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000268#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000271#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000272#include <direct.h>
273#define NAMLEN(dirent) strlen((dirent)->d_name)
274#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000278#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000280#endif
281#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#endif
284#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000286#endif
287#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000288
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000289#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000290#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000292#endif
293#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000294#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#endif
296#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000297#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000299#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000300#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000301#endif
302#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000303#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#endif
305#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000306#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000307#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000308#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000309#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000310#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000311#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000312#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000313#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
314#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000315static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000316#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318
Guido van Rossumd48f2521997-12-05 22:19:34 +0000319#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000320#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000321#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322
Tim Petersbc2e10e2002-03-03 23:17:02 +0000323#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324#if defined(PATH_MAX) && PATH_MAX > 1024
325#define MAXPATHLEN PATH_MAX
326#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000329#endif /* MAXPATHLEN */
330
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000331#ifdef UNION_WAIT
332/* Emulate some macros on systems that have a union instead of macros */
333
334#ifndef WIFEXITED
335#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
336#endif
337
338#ifndef WEXITSTATUS
339#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
340#endif
341
342#ifndef WTERMSIG
343#define WTERMSIG(u_wait) ((u_wait).w_termsig)
344#endif
345
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000346#define WAIT_TYPE union wait
347#define WAIT_STATUS_INT(s) (s.w_status)
348
349#else /* !UNION_WAIT */
350#define WAIT_TYPE int
351#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000352#endif /* UNION_WAIT */
353
Greg Wardb48bc172000-03-01 21:51:56 +0000354/* Don't use the "_r" form if we don't need it (also, won't have a
355 prototype for it, at least on Solaris -- maybe others as well?). */
356#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
357#define USE_CTERMID_R
358#endif
359
Fred Drake699f3522000-06-29 21:12:41 +0000360/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000361#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000362#undef FSTAT
363#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000364#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define STAT win32_stat
366# define FSTAT win32_fstat
367# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000368#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define STAT stat
370# define FSTAT fstat
371# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000372#endif
373
Tim Peters11b23062003-04-23 02:39:17 +0000374#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000375#include <sys/mkdev.h>
376#else
377#if defined(MAJOR_IN_SYSMACROS)
378#include <sys/sysmacros.h>
379#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000380#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
381#include <sys/mkdev.h>
382#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000383#endif
Fred Drake699f3522000-06-29 21:12:41 +0000384
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200385/* A helper used by a number of POSIX-only functions */
386#ifndef MS_WINDOWS
Georg Brandla391b112011-02-25 15:23:18 +0000387static int
388_parse_off_t(PyObject* arg, void* addr)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000389{
390#if !defined(HAVE_LARGEFILE_SUPPORT)
391 *((off_t*)addr) = PyLong_AsLong(arg);
392#else
Antoine Pitroudcc20b82011-02-26 13:38:35 +0000393 *((off_t*)addr) = PyLong_AsLongLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000394#endif
395 if (PyErr_Occurred())
396 return 0;
397 return 1;
398}
Ross Lagerwallb1e5d592011-09-19 08:30:43 +0200399#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000400
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000401#if defined _MSC_VER && _MSC_VER >= 1400
402/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
403 * valid and throw an assertion if it isn't.
404 * Normally, an invalid fd is likely to be a C program error and therefore
405 * an assertion can be useful, but it does contradict the POSIX standard
406 * which for write(2) states:
407 * "Otherwise, -1 shall be returned and errno set to indicate the error."
408 * "[EBADF] The fildes argument is not a valid file descriptor open for
409 * writing."
410 * Furthermore, python allows the user to enter any old integer
411 * as a fd and should merely raise a python exception on error.
412 * The Microsoft CRT doesn't provide an official way to check for the
413 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000414 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000415 * internal structures involved.
416 * The structures below must be updated for each version of visual studio
417 * according to the file internal.h in the CRT source, until MS comes
418 * up with a less hacky way to do this.
419 * (all of this is to avoid globally modifying the CRT behaviour using
420 * _set_invalid_parameter_handler() and _CrtSetReportMode())
421 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000422/* The actual size of the structure is determined at runtime.
423 * Only the first items must be present.
424 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000425typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000426 intptr_t osfhnd;
427 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000428} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000429
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000430extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000431#define IOINFO_L2E 5
432#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
433#define IOINFO_ARRAYS 64
434#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
435#define FOPEN 0x01
436#define _NO_CONSOLE_FILENO (intptr_t)-2
437
438/* This function emulates what the windows CRT does to validate file handles */
439int
440_PyVerify_fd(int fd)
441{
Victor Stinner8c62be82010-05-06 00:08:46 +0000442 const int i1 = fd >> IOINFO_L2E;
443 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000444
Antoine Pitrou22e41552010-08-15 18:07:50 +0000445 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000446
Victor Stinner8c62be82010-05-06 00:08:46 +0000447 /* Determine the actual size of the ioinfo structure,
448 * as used by the CRT loaded in memory
449 */
450 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
451 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
452 }
453 if (sizeof_ioinfo == 0) {
454 /* This should not happen... */
455 goto fail;
456 }
457
458 /* See that it isn't a special CLEAR fileno */
459 if (fd != _NO_CONSOLE_FILENO) {
460 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
461 * we check pointer validity and other info
462 */
463 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
464 /* finally, check that the file is open */
465 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
466 if (info->osfile & FOPEN) {
467 return 1;
468 }
469 }
470 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000471 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000472 errno = EBADF;
473 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000474}
475
476/* the special case of checking dup2. The target fd must be in a sensible range */
477static int
478_PyVerify_fd_dup2(int fd1, int fd2)
479{
Victor Stinner8c62be82010-05-06 00:08:46 +0000480 if (!_PyVerify_fd(fd1))
481 return 0;
482 if (fd2 == _NO_CONSOLE_FILENO)
483 return 0;
484 if ((unsigned)fd2 < _NHANDLE_)
485 return 1;
486 else
487 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000488}
489#else
490/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
491#define _PyVerify_fd_dup2(A, B) (1)
492#endif
493
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000494#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +0000495/* The following structure was copied from
496 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
497 include doesn't seem to be present in the Windows SDK (at least as included
498 with Visual Studio Express). */
499typedef struct _REPARSE_DATA_BUFFER {
500 ULONG ReparseTag;
501 USHORT ReparseDataLength;
502 USHORT Reserved;
503 union {
504 struct {
505 USHORT SubstituteNameOffset;
506 USHORT SubstituteNameLength;
507 USHORT PrintNameOffset;
508 USHORT PrintNameLength;
509 ULONG Flags;
510 WCHAR PathBuffer[1];
511 } SymbolicLinkReparseBuffer;
512
513 struct {
514 USHORT SubstituteNameOffset;
515 USHORT SubstituteNameLength;
516 USHORT PrintNameOffset;
517 USHORT PrintNameLength;
518 WCHAR PathBuffer[1];
519 } MountPointReparseBuffer;
520
521 struct {
522 UCHAR DataBuffer[1];
523 } GenericReparseBuffer;
524 };
525} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
526
527#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
528 GenericReparseBuffer)
529#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
530
531static int
Brian Curtind25aef52011-06-13 15:16:04 -0500532win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +0000533{
534 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
535 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
536 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000537
538 if (0 == DeviceIoControl(
539 reparse_point_handle,
540 FSCTL_GET_REPARSE_POINT,
541 NULL, 0, /* in buffer */
542 target_buffer, sizeof(target_buffer),
543 &n_bytes_returned,
544 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -0500545 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000546
547 if (reparse_tag)
548 *reparse_tag = rdb->ReparseTag;
549
Brian Curtind25aef52011-06-13 15:16:04 -0500550 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +0000551}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100552
553static int
554win32_warn_bytes_api()
555{
556 return PyErr_WarnEx(PyExc_DeprecationWarning,
557 "The Windows bytes API has been deprecated, "
558 "use Unicode filenames instead",
559 1);
560}
561
562static PyObject*
563win32_decode_filename(PyObject *obj)
564{
565 PyObject *unicode;
566 if (PyUnicode_Check(obj)) {
567 if (PyUnicode_READY(obj))
568 return NULL;
569 Py_INCREF(obj);
570 return obj;
571 }
572 if (!PyUnicode_FSDecoder(obj, &unicode))
573 return NULL;
574 if (win32_warn_bytes_api()) {
575 Py_DECREF(unicode);
576 return NULL;
577 }
578 return unicode;
579}
Brian Curtinfc1be6d2010-11-24 13:23:18 +0000580#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +0000581
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000582/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000583#ifdef WITH_NEXT_FRAMEWORK
584/* On Darwin/MacOSX a shared library or framework has no access to
585** environ directly, we must obtain it with _NSGetEnviron().
586*/
587#include <crt_externs.h>
588static char **environ;
589#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000590extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000591#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000592
Barry Warsaw53699e91996-12-10 23:23:01 +0000593static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000594convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595{
Victor Stinner8c62be82010-05-06 00:08:46 +0000596 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000597#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000598 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000599#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000600 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000601#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000602#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000603 APIRET rc;
604 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
605#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000606
Victor Stinner8c62be82010-05-06 00:08:46 +0000607 d = PyDict_New();
608 if (d == NULL)
609 return NULL;
610#ifdef WITH_NEXT_FRAMEWORK
611 if (environ == NULL)
612 environ = *_NSGetEnviron();
613#endif
614#ifdef MS_WINDOWS
615 /* _wenviron must be initialized in this way if the program is started
616 through main() instead of wmain(). */
617 _wgetenv(L"");
618 if (_wenviron == NULL)
619 return d;
620 /* This part ignores errors */
621 for (e = _wenviron; *e != NULL; e++) {
622 PyObject *k;
623 PyObject *v;
624 wchar_t *p = wcschr(*e, L'=');
625 if (p == NULL)
626 continue;
627 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
628 if (k == NULL) {
629 PyErr_Clear();
630 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000631 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000632 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
633 if (v == NULL) {
634 PyErr_Clear();
635 Py_DECREF(k);
636 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000637 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000638 if (PyDict_GetItem(d, k) == NULL) {
639 if (PyDict_SetItem(d, k, v) != 0)
640 PyErr_Clear();
641 }
642 Py_DECREF(k);
643 Py_DECREF(v);
644 }
645#else
646 if (environ == NULL)
647 return d;
648 /* This part ignores errors */
649 for (e = environ; *e != NULL; e++) {
650 PyObject *k;
651 PyObject *v;
652 char *p = strchr(*e, '=');
653 if (p == NULL)
654 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000655 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000656 if (k == NULL) {
657 PyErr_Clear();
658 continue;
659 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000660 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000661 if (v == NULL) {
662 PyErr_Clear();
663 Py_DECREF(k);
664 continue;
665 }
666 if (PyDict_GetItem(d, k) == NULL) {
667 if (PyDict_SetItem(d, k, v) != 0)
668 PyErr_Clear();
669 }
670 Py_DECREF(k);
671 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000672 }
673#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000674#if defined(PYOS_OS2)
675 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
676 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
677 PyObject *v = PyBytes_FromString(buffer);
678 PyDict_SetItemString(d, "BEGINLIBPATH", v);
679 Py_DECREF(v);
680 }
681 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
682 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
683 PyObject *v = PyBytes_FromString(buffer);
684 PyDict_SetItemString(d, "ENDLIBPATH", v);
685 Py_DECREF(v);
686 }
687#endif
688 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000689}
690
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691/* Set a POSIX-specific error from errno, and return NULL */
692
Barry Warsawd58d7641998-07-23 16:14:40 +0000693static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000694posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000695{
Victor Stinner8c62be82010-05-06 00:08:46 +0000696 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000697}
Barry Warsawd58d7641998-07-23 16:14:40 +0000698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000699posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000700{
Victor Stinner8c62be82010-05-06 00:08:46 +0000701 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000702}
703
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000704
Mark Hammondef8b6542001-05-13 08:04:26 +0000705static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000706posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000707{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000708 PyObject *name_str, *rc;
709 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
710 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000711 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000712 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
713 name_str);
714 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000715 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000716}
717
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000718#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000719static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000720win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000721{
Victor Stinner8c62be82010-05-06 00:08:46 +0000722 /* XXX We should pass the function name along in the future.
723 (winreg.c also wants to pass the function name.)
724 This would however require an additional param to the
725 Windows error object, which is non-trivial.
726 */
727 errno = GetLastError();
728 if (filename)
729 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
730 else
731 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000732}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000733
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000734static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +0200735win32_error_unicode(char* function, wchar_t* filename)
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000736{
Victor Stinner8c62be82010-05-06 00:08:46 +0000737 /* XXX - see win32_error for comments on 'function' */
738 errno = GetLastError();
739 if (filename)
740 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
741 else
742 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000743}
744
Victor Stinnereb5657a2011-09-30 01:44:27 +0200745static PyObject *
746win32_error_object(char* function, PyObject* filename)
747{
748 /* XXX - see win32_error for comments on 'function' */
749 errno = GetLastError();
750 if (filename)
751 return PyErr_SetExcFromWindowsErrWithFilenameObject(
752 PyExc_WindowsError,
753 errno,
754 filename);
755 else
756 return PyErr_SetFromWindowsErr(errno);
757}
758
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000759#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000760
Guido van Rossumd48f2521997-12-05 22:19:34 +0000761#if defined(PYOS_OS2)
762/**********************************************************************
763 * Helper Function to Trim and Format OS/2 Messages
764 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000765static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000766os2_formatmsg(char *msgbuf, int msglen, char *reason)
767{
768 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
769
770 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
771 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
772
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000773 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000774 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
775 }
776
777 /* Add Optional Reason Text */
778 if (reason) {
779 strcat(msgbuf, " : ");
780 strcat(msgbuf, reason);
781 }
782}
783
784/**********************************************************************
785 * Decode an OS/2 Operating System Error Code
786 *
787 * A convenience function to lookup an OS/2 error code and return a
788 * text message we can use to raise a Python exception.
789 *
790 * Notes:
791 * The messages for errors returned from the OS/2 kernel reside in
792 * the file OSO001.MSG in the \OS2 directory hierarchy.
793 *
794 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000795static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000796os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
797{
798 APIRET rc;
799 ULONG msglen;
800
801 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
802 Py_BEGIN_ALLOW_THREADS
803 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
804 errorcode, "oso001.msg", &msglen);
805 Py_END_ALLOW_THREADS
806
807 if (rc == NO_ERROR)
808 os2_formatmsg(msgbuf, msglen, reason);
809 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000810 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000811 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000812
813 return msgbuf;
814}
815
816/* Set an OS/2-specific error and return NULL. OS/2 kernel
817 errors are not in a global variable e.g. 'errno' nor are
818 they congruent with posix error numbers. */
819
Victor Stinner8c62be82010-05-06 00:08:46 +0000820static PyObject *
821os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000822{
823 char text[1024];
824 PyObject *v;
825
826 os2_strerror(text, sizeof(text), code, "");
827
828 v = Py_BuildValue("(is)", code, text);
829 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000830 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000831 Py_DECREF(v);
832 }
833 return NULL; /* Signal to Python that an Exception is Pending */
834}
835
836#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000837
838/* POSIX generic methods */
839
Barry Warsaw53699e91996-12-10 23:23:01 +0000840static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000841posix_fildes(PyObject *fdobj, int (*func)(int))
842{
Victor Stinner8c62be82010-05-06 00:08:46 +0000843 int fd;
844 int res;
845 fd = PyObject_AsFileDescriptor(fdobj);
846 if (fd < 0)
847 return NULL;
848 if (!_PyVerify_fd(fd))
849 return posix_error();
850 Py_BEGIN_ALLOW_THREADS
851 res = (*func)(fd);
852 Py_END_ALLOW_THREADS
853 if (res < 0)
854 return posix_error();
855 Py_INCREF(Py_None);
856 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000857}
Guido van Rossum21142a01999-01-08 21:05:37 +0000858
859static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000860posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861{
Victor Stinner8c62be82010-05-06 00:08:46 +0000862 PyObject *opath1 = NULL;
863 char *path1;
864 int res;
865 if (!PyArg_ParseTuple(args, format,
866 PyUnicode_FSConverter, &opath1))
867 return NULL;
868 path1 = PyBytes_AsString(opath1);
869 Py_BEGIN_ALLOW_THREADS
870 res = (*func)(path1);
871 Py_END_ALLOW_THREADS
872 if (res < 0)
873 return posix_error_with_allocated_filename(opath1);
874 Py_DECREF(opath1);
875 Py_INCREF(Py_None);
876 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000877}
878
Barry Warsaw53699e91996-12-10 23:23:01 +0000879static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000880posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000881 char *format,
882 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000883{
Victor Stinner8c62be82010-05-06 00:08:46 +0000884 PyObject *opath1 = NULL, *opath2 = NULL;
885 char *path1, *path2;
886 int res;
887 if (!PyArg_ParseTuple(args, format,
888 PyUnicode_FSConverter, &opath1,
889 PyUnicode_FSConverter, &opath2)) {
890 return NULL;
891 }
892 path1 = PyBytes_AsString(opath1);
893 path2 = PyBytes_AsString(opath2);
894 Py_BEGIN_ALLOW_THREADS
895 res = (*func)(path1, path2);
896 Py_END_ALLOW_THREADS
897 Py_DECREF(opath1);
898 Py_DECREF(opath2);
899 if (res != 0)
900 /* XXX how to report both path1 and path2??? */
901 return posix_error();
902 Py_INCREF(Py_None);
903 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000904}
905
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000906#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000907static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000908win32_1str(PyObject* args, char* func,
909 char* format, BOOL (__stdcall *funcA)(LPCSTR),
910 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000911{
Victor Stinner8c62be82010-05-06 00:08:46 +0000912 PyObject *uni;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100913 const char *ansi;
Victor Stinner8c62be82010-05-06 00:08:46 +0000914 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000915
Victor Stinnereb5657a2011-09-30 01:44:27 +0200916 if (PyArg_ParseTuple(args, wformat, &uni))
917 {
918 wchar_t *wstr = PyUnicode_AsUnicode(uni);
919 if (wstr == NULL)
920 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000921 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +0200922 result = funcW(wstr);
Victor Stinner8c62be82010-05-06 00:08:46 +0000923 Py_END_ALLOW_THREADS
924 if (!result)
Victor Stinnereb5657a2011-09-30 01:44:27 +0200925 return win32_error_object(func, uni);
Victor Stinner8c62be82010-05-06 00:08:46 +0000926 Py_INCREF(Py_None);
927 return Py_None;
928 }
Victor Stinnereb5657a2011-09-30 01:44:27 +0200929 PyErr_Clear();
930
Victor Stinner8c62be82010-05-06 00:08:46 +0000931 if (!PyArg_ParseTuple(args, format, &ansi))
932 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +0100933 if (win32_warn_bytes_api())
934 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +0000935 Py_BEGIN_ALLOW_THREADS
936 result = funcA(ansi);
937 Py_END_ALLOW_THREADS
938 if (!result)
939 return win32_error(func, ansi);
940 Py_INCREF(Py_None);
941 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000942
943}
944
945/* This is a reimplementation of the C library's chdir function,
946 but one that produces Win32 errors instead of DOS error codes.
947 chdir is essentially a wrapper around SetCurrentDirectory; however,
948 it also needs to set "magic" environment variables indicating
949 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000950static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000951win32_chdir(LPCSTR path)
952{
Victor Stinner8c62be82010-05-06 00:08:46 +0000953 char new_path[MAX_PATH+1];
954 int result;
955 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000956
Victor Stinner8c62be82010-05-06 00:08:46 +0000957 if(!SetCurrentDirectoryA(path))
958 return FALSE;
959 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
960 if (!result)
961 return FALSE;
962 /* In the ANSI API, there should not be any paths longer
963 than MAX_PATH. */
964 assert(result <= MAX_PATH+1);
965 if (strncmp(new_path, "\\\\", 2) == 0 ||
966 strncmp(new_path, "//", 2) == 0)
967 /* UNC path, nothing to do. */
968 return TRUE;
969 env[1] = new_path[0];
970 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000971}
972
973/* The Unicode version differs from the ANSI version
974 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000975static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000976win32_wchdir(LPCWSTR path)
977{
Victor Stinner8c62be82010-05-06 00:08:46 +0000978 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
979 int result;
980 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000981
Victor Stinner8c62be82010-05-06 00:08:46 +0000982 if(!SetCurrentDirectoryW(path))
983 return FALSE;
984 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
985 if (!result)
986 return FALSE;
987 if (result > MAX_PATH+1) {
988 new_path = malloc(result * sizeof(wchar_t));
989 if (!new_path) {
990 SetLastError(ERROR_OUTOFMEMORY);
991 return FALSE;
992 }
993 result = GetCurrentDirectoryW(result, new_path);
994 if (!result) {
995 free(new_path);
996 return FALSE;
997 }
998 }
999 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1000 wcsncmp(new_path, L"//", 2) == 0)
1001 /* UNC path, nothing to do. */
1002 return TRUE;
1003 env[1] = new_path[0];
1004 result = SetEnvironmentVariableW(env, new_path);
1005 if (new_path != _new_path)
1006 free(new_path);
1007 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001008}
1009#endif
1010
Martin v. Löwis14694662006-02-03 12:54:16 +00001011#ifdef MS_WINDOWS
1012/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1013 - time stamps are restricted to second resolution
1014 - file modification times suffer from forth-and-back conversions between
1015 UTC and local time
1016 Therefore, we implement our own stat, based on the Win32 API directly.
1017*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001018#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001019
1020struct win32_stat{
1021 int st_dev;
1022 __int64 st_ino;
1023 unsigned short st_mode;
1024 int st_nlink;
1025 int st_uid;
1026 int st_gid;
1027 int st_rdev;
1028 __int64 st_size;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001029 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001030 int st_atime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001031 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001032 int st_mtime_nsec;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001033 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001034 int st_ctime_nsec;
1035};
1036
1037static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1038
1039static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001040FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001041{
Victor Stinner8c62be82010-05-06 00:08:46 +00001042 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1043 /* Cannot simply cast and dereference in_ptr,
1044 since it might not be aligned properly */
1045 __int64 in;
1046 memcpy(&in, in_ptr, sizeof(in));
1047 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001048 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001049}
1050
Thomas Wouters477c8d52006-05-27 19:21:47 +00001051static void
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00001052time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001053{
Victor Stinner8c62be82010-05-06 00:08:46 +00001054 /* XXX endianness */
1055 __int64 out;
1056 out = time_in + secs_between_epochs;
1057 out = out * 10000000 + nsec_in / 100;
1058 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001059}
1060
Martin v. Löwis14694662006-02-03 12:54:16 +00001061/* Below, we *know* that ugo+r is 0444 */
1062#if _S_IREAD != 0400
1063#error Unsupported C library
1064#endif
1065static int
1066attributes_to_mode(DWORD attr)
1067{
Victor Stinner8c62be82010-05-06 00:08:46 +00001068 int m = 0;
1069 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1070 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1071 else
1072 m |= _S_IFREG;
1073 if (attr & FILE_ATTRIBUTE_READONLY)
1074 m |= 0444;
1075 else
1076 m |= 0666;
1077 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001078}
1079
1080static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001081attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001082{
Victor Stinner8c62be82010-05-06 00:08:46 +00001083 memset(result, 0, sizeof(*result));
1084 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1085 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1086 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1087 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1088 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001089 result->st_nlink = info->nNumberOfLinks;
Brian Curtin1b9df392010-11-24 20:24:31 +00001090 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001091 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1092 /* first clear the S_IFMT bits */
1093 result->st_mode ^= (result->st_mode & 0170000);
1094 /* now set the bits that make this a symlink */
1095 result->st_mode |= 0120000;
1096 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001097
Victor Stinner8c62be82010-05-06 00:08:46 +00001098 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001099}
1100
Guido van Rossumd8faa362007-04-27 19:54:29 +00001101static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001102attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001103{
Victor Stinner8c62be82010-05-06 00:08:46 +00001104 HANDLE hFindFile;
1105 WIN32_FIND_DATAA FileData;
1106 hFindFile = FindFirstFileA(pszFile, &FileData);
1107 if (hFindFile == INVALID_HANDLE_VALUE)
1108 return FALSE;
1109 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001110 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001111 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112 info->dwFileAttributes = FileData.dwFileAttributes;
1113 info->ftCreationTime = FileData.ftCreationTime;
1114 info->ftLastAccessTime = FileData.ftLastAccessTime;
1115 info->ftLastWriteTime = FileData.ftLastWriteTime;
1116 info->nFileSizeHigh = FileData.nFileSizeHigh;
1117 info->nFileSizeLow = FileData.nFileSizeLow;
1118/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001119 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1120 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001121 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001122}
1123
1124static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001125attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001126{
Victor Stinner8c62be82010-05-06 00:08:46 +00001127 HANDLE hFindFile;
1128 WIN32_FIND_DATAW FileData;
1129 hFindFile = FindFirstFileW(pszFile, &FileData);
1130 if (hFindFile == INVALID_HANDLE_VALUE)
1131 return FALSE;
1132 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001133 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001134 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001135 info->dwFileAttributes = FileData.dwFileAttributes;
1136 info->ftCreationTime = FileData.ftCreationTime;
1137 info->ftLastAccessTime = FileData.ftLastAccessTime;
1138 info->ftLastWriteTime = FileData.ftLastWriteTime;
1139 info->nFileSizeHigh = FileData.nFileSizeHigh;
1140 info->nFileSizeLow = FileData.nFileSizeLow;
1141/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001142 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1143 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001144 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001145}
1146
Brian Curtind25aef52011-06-13 15:16:04 -05001147/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1148static int has_GetFinalPathNameByHandle = 0;
Brian Curtind25aef52011-06-13 15:16:04 -05001149static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1150 DWORD);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001151static int
Brian Curtind25aef52011-06-13 15:16:04 -05001152check_GetFinalPathNameByHandle()
Brian Curtinf5e76d02010-11-24 13:14:05 +00001153{
Brian Curtind25aef52011-06-13 15:16:04 -05001154 HINSTANCE hKernel32;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001155 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1156 DWORD);
1157
Brian Curtind25aef52011-06-13 15:16:04 -05001158 /* only recheck */
1159 if (!has_GetFinalPathNameByHandle)
1160 {
Martin v. Löwis50590f12012-01-14 17:54:09 +01001161 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtind25aef52011-06-13 15:16:04 -05001162 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1163 "GetFinalPathNameByHandleA");
1164 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1165 "GetFinalPathNameByHandleW");
1166 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1167 Py_GetFinalPathNameByHandleW;
1168 }
1169 return has_GetFinalPathNameByHandle;
1170}
1171
1172static BOOL
1173get_target_path(HANDLE hdl, wchar_t **target_path)
1174{
1175 int buf_size, result_length;
1176 wchar_t *buf;
1177
1178 /* We have a good handle to the target, use it to determine
1179 the target path name (then we'll call lstat on it). */
1180 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0,
1181 VOLUME_NAME_DOS);
1182 if(!buf_size)
1183 return FALSE;
1184
1185 buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001186 if (!buf) {
1187 SetLastError(ERROR_OUTOFMEMORY);
1188 return FALSE;
1189 }
1190
Brian Curtind25aef52011-06-13 15:16:04 -05001191 result_length = Py_GetFinalPathNameByHandleW(hdl,
1192 buf, buf_size, VOLUME_NAME_DOS);
1193
1194 if(!result_length) {
1195 free(buf);
1196 return FALSE;
1197 }
1198
1199 if(!CloseHandle(hdl)) {
1200 free(buf);
1201 return FALSE;
1202 }
1203
1204 buf[result_length] = 0;
1205
1206 *target_path = buf;
1207 return TRUE;
1208}
1209
1210static int
1211win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1212 BOOL traverse);
1213static int
1214win32_xstat_impl(const char *path, struct win32_stat *result,
1215 BOOL traverse)
1216{
Victor Stinner26de69d2011-06-17 15:15:38 +02001217 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001218 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001219 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001220 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001221 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001222 const char *dot;
1223
Brian Curtind25aef52011-06-13 15:16:04 -05001224 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001225 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1226 traverse reparse point. */
1227 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001228 }
1229
Brian Curtinf5e76d02010-11-24 13:14:05 +00001230 hFile = CreateFileA(
1231 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001232 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001233 0, /* share mode */
1234 NULL, /* security attributes */
1235 OPEN_EXISTING,
1236 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001237 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1238 Because of this, calls like GetFinalPathNameByHandle will return
1239 the symlink path agin and not the actual final path. */
1240 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1241 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001242 NULL);
1243
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001244 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001245 /* Either the target doesn't exist, or we don't have access to
1246 get a handle to it. If the former, we need to return an error.
1247 If the latter, we can use attributes_from_dir. */
1248 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001249 return -1;
1250 /* Could not get attributes on open file. Fall back to
1251 reading the directory. */
1252 if (!attributes_from_dir(path, &info, &reparse_tag))
1253 /* Very strange. This should not fail now */
1254 return -1;
1255 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1256 if (traverse) {
1257 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001258 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001259 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001260 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001261 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001262 } else {
1263 if (!GetFileInformationByHandle(hFile, &info)) {
1264 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001265 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001266 }
1267 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001268 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1269 return -1;
1270
1271 /* Close the outer open file handle now that we're about to
1272 reopen it with different flags. */
1273 if (!CloseHandle(hFile))
1274 return -1;
1275
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001276 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001277 /* In order to call GetFinalPathNameByHandle we need to open
1278 the file without the reparse handling flag set. */
1279 hFile2 = CreateFileA(
1280 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1281 NULL, OPEN_EXISTING,
1282 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1283 NULL);
1284 if (hFile2 == INVALID_HANDLE_VALUE)
1285 return -1;
1286
1287 if (!get_target_path(hFile2, &target_path))
1288 return -1;
1289
1290 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001291 free(target_path);
1292 return code;
1293 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001294 } else
1295 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001296 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001297 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001298
1299 /* Set S_IEXEC if it is an .exe, .bat, ... */
1300 dot = strrchr(path, '.');
1301 if (dot) {
1302 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1303 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1304 result->st_mode |= 0111;
1305 }
1306 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001307}
1308
1309static int
Brian Curtind25aef52011-06-13 15:16:04 -05001310win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result,
1311 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001312{
1313 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001314 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001315 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001316 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001317 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001318 const wchar_t *dot;
1319
Brian Curtind25aef52011-06-13 15:16:04 -05001320 if(!check_GetFinalPathNameByHandle()) {
Brian Curtinc8be8402011-06-14 09:52:50 -05001321 /* If the OS doesn't have GetFinalPathNameByHandle, don't
1322 traverse reparse point. */
1323 traverse = FALSE;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001324 }
1325
Brian Curtinf5e76d02010-11-24 13:14:05 +00001326 hFile = CreateFileW(
1327 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001328 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001329 0, /* share mode */
1330 NULL, /* security attributes */
1331 OPEN_EXISTING,
1332 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001333 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1334 Because of this, calls like GetFinalPathNameByHandle will return
1335 the symlink path agin and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001336 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001337 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001338 NULL);
1339
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001340 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001341 /* Either the target doesn't exist, or we don't have access to
1342 get a handle to it. If the former, we need to return an error.
1343 If the latter, we can use attributes_from_dir. */
1344 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001345 return -1;
1346 /* Could not get attributes on open file. Fall back to
1347 reading the directory. */
1348 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1349 /* Very strange. This should not fail now */
1350 return -1;
1351 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1352 if (traverse) {
1353 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001354 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001355 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001356 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001357 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001358 } else {
1359 if (!GetFileInformationByHandle(hFile, &info)) {
1360 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001361 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001362 }
1363 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001364 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1365 return -1;
1366
1367 /* Close the outer open file handle now that we're about to
1368 reopen it with different flags. */
1369 if (!CloseHandle(hFile))
1370 return -1;
1371
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001372 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001373 /* In order to call GetFinalPathNameByHandle we need to open
1374 the file without the reparse handling flag set. */
1375 hFile2 = CreateFileW(
1376 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1377 NULL, OPEN_EXISTING,
1378 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1379 NULL);
1380 if (hFile2 == INVALID_HANDLE_VALUE)
1381 return -1;
1382
1383 if (!get_target_path(hFile2, &target_path))
1384 return -1;
1385
1386 code = win32_xstat_impl_w(target_path, result, FALSE);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001387 free(target_path);
1388 return code;
1389 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001390 } else
1391 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001392 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001393 attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001394
1395 /* Set S_IEXEC if it is an .exe, .bat, ... */
1396 dot = wcsrchr(path, '.');
1397 if (dot) {
1398 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1399 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1400 result->st_mode |= 0111;
1401 }
1402 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001403}
1404
1405static int
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001406win32_xstat(const char *path, struct win32_stat *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001407{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001408 /* Protocol violation: we explicitly clear errno, instead of
1409 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001410 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001411 errno = 0;
1412 return code;
1413}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001414
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001415static int
1416win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse)
1417{
1418 /* Protocol violation: we explicitly clear errno, instead of
1419 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001420 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001421 errno = 0;
1422 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001423}
Brian Curtind25aef52011-06-13 15:16:04 -05001424/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001425
1426 In Posix, stat automatically traverses symlinks and returns the stat
1427 structure for the target. In Windows, the equivalent GetFileAttributes by
1428 default does not traverse symlinks and instead returns attributes for
1429 the symlink.
1430
1431 Therefore, win32_lstat will get the attributes traditionally, and
1432 win32_stat will first explicitly resolve the symlink target and then will
1433 call win32_lstat on that result.
1434
Ezio Melotti4969f702011-03-15 05:59:46 +02001435 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001436
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001437static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001438win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001439{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001440 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001441}
1442
Victor Stinner8c62be82010-05-06 00:08:46 +00001443static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001444win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001445{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001446 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001447}
1448
1449static int
1450win32_stat(const char* path, struct win32_stat *result)
1451{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001452 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001453}
1454
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001455static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001456win32_stat_w(const wchar_t* path, struct win32_stat *result)
1457{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001458 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001459}
1460
1461static int
1462win32_fstat(int file_number, struct win32_stat *result)
1463{
Victor Stinner8c62be82010-05-06 00:08:46 +00001464 BY_HANDLE_FILE_INFORMATION info;
1465 HANDLE h;
1466 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001467
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001469
Victor Stinner8c62be82010-05-06 00:08:46 +00001470 /* Protocol violation: we explicitly clear errno, instead of
1471 setting it to a POSIX error. Callers should use GetLastError. */
1472 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001473
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 if (h == INVALID_HANDLE_VALUE) {
1475 /* This is really a C library error (invalid file handle).
1476 We set the Win32 error to the closes one matching. */
1477 SetLastError(ERROR_INVALID_HANDLE);
1478 return -1;
1479 }
1480 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001481
Victor Stinner8c62be82010-05-06 00:08:46 +00001482 type = GetFileType(h);
1483 if (type == FILE_TYPE_UNKNOWN) {
1484 DWORD error = GetLastError();
1485 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001486 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001487 }
1488 /* else: valid but unknown file */
1489 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001490
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 if (type != FILE_TYPE_DISK) {
1492 if (type == FILE_TYPE_CHAR)
1493 result->st_mode = _S_IFCHR;
1494 else if (type == FILE_TYPE_PIPE)
1495 result->st_mode = _S_IFIFO;
1496 return 0;
1497 }
1498
1499 if (!GetFileInformationByHandle(h, &info)) {
1500 return -1;
1501 }
1502
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001503 attribute_data_to_stat(&info, 0, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001504 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1506 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001507}
1508
1509#endif /* MS_WINDOWS */
1510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001511PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001512"stat_result: Result from stat or lstat.\n\n\
1513This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001514 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001515or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1516\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001517Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1518or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001519\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001520See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001521
1522static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 {"st_mode", "protection bits"},
1524 {"st_ino", "inode"},
1525 {"st_dev", "device"},
1526 {"st_nlink", "number of hard links"},
1527 {"st_uid", "user ID of owner"},
1528 {"st_gid", "group ID of owner"},
1529 {"st_size", "total size, in bytes"},
1530 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1531 {NULL, "integer time of last access"},
1532 {NULL, "integer time of last modification"},
1533 {NULL, "integer time of last change"},
1534 {"st_atime", "time of last access"},
1535 {"st_mtime", "time of last modification"},
1536 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001537#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001538 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001539#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001540#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001542#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001543#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001545#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001546#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001548#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001549#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001550 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001551#endif
1552#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001553 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001554#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001556};
1557
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001558#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001559#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001560#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001561#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001562#endif
1563
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001564#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001565#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1566#else
1567#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1568#endif
1569
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001570#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001571#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1572#else
1573#define ST_RDEV_IDX ST_BLOCKS_IDX
1574#endif
1575
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001576#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1577#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1578#else
1579#define ST_FLAGS_IDX ST_RDEV_IDX
1580#endif
1581
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001582#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001583#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001584#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001585#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001586#endif
1587
1588#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1589#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1590#else
1591#define ST_BIRTHTIME_IDX ST_GEN_IDX
1592#endif
1593
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001594static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001595 "stat_result", /* name */
1596 stat_result__doc__, /* doc */
1597 stat_result_fields,
1598 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001599};
1600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001601PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001602"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1603This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001604 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001605or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001606\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001607See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001608
1609static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001610 {"f_bsize", },
1611 {"f_frsize", },
1612 {"f_blocks", },
1613 {"f_bfree", },
1614 {"f_bavail", },
1615 {"f_files", },
1616 {"f_ffree", },
1617 {"f_favail", },
1618 {"f_flag", },
1619 {"f_namemax",},
1620 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001621};
1622
1623static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001624 "statvfs_result", /* name */
1625 statvfs_result__doc__, /* doc */
1626 statvfs_result_fields,
1627 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001628};
1629
Ross Lagerwall7807c352011-03-17 20:20:30 +02001630#if defined(HAVE_WAITID) && !defined(__APPLE__)
1631PyDoc_STRVAR(waitid_result__doc__,
1632"waitid_result: Result from waitid.\n\n\
1633This object may be accessed either as a tuple of\n\
1634 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1635or via the attributes si_pid, si_uid, and so on.\n\
1636\n\
1637See os.waitid for more information.");
1638
1639static PyStructSequence_Field waitid_result_fields[] = {
1640 {"si_pid", },
1641 {"si_uid", },
1642 {"si_signo", },
1643 {"si_status", },
1644 {"si_code", },
1645 {0}
1646};
1647
1648static PyStructSequence_Desc waitid_result_desc = {
1649 "waitid_result", /* name */
1650 waitid_result__doc__, /* doc */
1651 waitid_result_fields,
1652 5
1653};
1654static PyTypeObject WaitidResultType;
1655#endif
1656
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001657static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001658static PyTypeObject StatResultType;
1659static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001660#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001661static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001662#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001663static newfunc structseq_new;
1664
1665static PyObject *
1666statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1667{
Victor Stinner8c62be82010-05-06 00:08:46 +00001668 PyStructSequence *result;
1669 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001670
Victor Stinner8c62be82010-05-06 00:08:46 +00001671 result = (PyStructSequence*)structseq_new(type, args, kwds);
1672 if (!result)
1673 return NULL;
1674 /* If we have been initialized from a tuple,
1675 st_?time might be set to None. Initialize it
1676 from the int slots. */
1677 for (i = 7; i <= 9; i++) {
1678 if (result->ob_item[i+3] == Py_None) {
1679 Py_DECREF(Py_None);
1680 Py_INCREF(result->ob_item[i]);
1681 result->ob_item[i+3] = result->ob_item[i];
1682 }
1683 }
1684 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001685}
1686
1687
1688
1689/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001690static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001691
1692PyDoc_STRVAR(stat_float_times__doc__,
1693"stat_float_times([newval]) -> oldval\n\n\
1694Determine whether os.[lf]stat represents time stamps as float objects.\n\
1695If newval is True, future calls to stat() return floats, if it is False,\n\
1696future calls return ints. \n\
1697If newval is omitted, return the current setting.\n");
1698
1699static PyObject*
1700stat_float_times(PyObject* self, PyObject *args)
1701{
Victor Stinner8c62be82010-05-06 00:08:46 +00001702 int newval = -1;
1703 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1704 return NULL;
Victor Stinnerccd57152012-02-08 14:31:50 +01001705 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1706 "os.stat_float_times() has been deprecated, "
1707 "use timestamp argument of os.stat() instead",
1708 1))
1709 return NULL;
1710
Victor Stinner8c62be82010-05-06 00:08:46 +00001711 if (newval == -1)
1712 /* Return old value */
1713 return PyBool_FromLong(_stat_float_times);
1714 _stat_float_times = newval;
1715 Py_INCREF(Py_None);
1716 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001717}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001718
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001719static void
Victor Stinnerccd57152012-02-08 14:31:50 +01001720fill_time(PyObject *v, int index, time_t sec, unsigned long nsec,
1721 int has_nsec, PyObject *timestamp)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001722{
Victor Stinner8c62be82010-05-06 00:08:46 +00001723 PyObject *fval,*ival;
Victor Stinnerccd57152012-02-08 14:31:50 +01001724 _PyTime_t ts;
1725
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001726#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001727 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001728#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001729 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001730#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001731 if (!ival)
1732 return;
Victor Stinnerccd57152012-02-08 14:31:50 +01001733 if (timestamp == NULL && _stat_float_times)
1734 timestamp = (PyObject*)&PyFloat_Type;
1735 if (timestamp != NULL) {
1736 ts.seconds = sec;
1737 if (has_nsec) {
1738 ts.numerator = nsec;
1739 ts.denominator = 1000000000;
1740 }
1741 else {
1742 ts.numerator = 0;
1743 ts.denominator = 1;
1744 }
1745 fval = _PyTime_Convert(&ts, timestamp);
1746 }
1747 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00001748 fval = ival;
1749 Py_INCREF(fval);
1750 }
1751 PyStructSequence_SET_ITEM(v, index, ival);
1752 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001753}
1754
Tim Peters5aa91602002-01-30 05:46:57 +00001755/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001756 (used by posix_stat() and posix_fstat()) */
1757static PyObject*
Victor Stinnerccd57152012-02-08 14:31:50 +01001758_pystat_fromstructstat(STRUCT_STAT *st, PyObject *timestamp)
Fred Drake699f3522000-06-29 21:12:41 +00001759{
Victor Stinner8c62be82010-05-06 00:08:46 +00001760 unsigned long ansec, mnsec, cnsec;
Victor Stinnerccd57152012-02-08 14:31:50 +01001761 int has_nsec;
1762#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1763 _PyTime_t ts;
1764#endif
1765
Victor Stinner8c62be82010-05-06 00:08:46 +00001766 PyObject *v = PyStructSequence_New(&StatResultType);
1767 if (v == NULL)
1768 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001769
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001771#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001772 PyStructSequence_SET_ITEM(v, 1,
1773 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001774#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001775 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001776#endif
1777#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001778 PyStructSequence_SET_ITEM(v, 2,
1779 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001780#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001782#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001783 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1784 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1785 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001786#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 PyStructSequence_SET_ITEM(v, 6,
1788 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001789#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001791#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001792
Martin v. Löwis14694662006-02-03 12:54:16 +00001793#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 ansec = st->st_atim.tv_nsec;
1795 mnsec = st->st_mtim.tv_nsec;
1796 cnsec = st->st_ctim.tv_nsec;
Victor Stinnerccd57152012-02-08 14:31:50 +01001797 has_nsec = 1;
Martin v. Löwis14694662006-02-03 12:54:16 +00001798#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001799 ansec = st->st_atimespec.tv_nsec;
1800 mnsec = st->st_mtimespec.tv_nsec;
1801 cnsec = st->st_ctimespec.tv_nsec;
Victor Stinnerccd57152012-02-08 14:31:50 +01001802 has_nsec = 1;
Martin v. Löwis14694662006-02-03 12:54:16 +00001803#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001804 ansec = st->st_atime_nsec;
1805 mnsec = st->st_mtime_nsec;
1806 cnsec = st->st_ctime_nsec;
Victor Stinnerccd57152012-02-08 14:31:50 +01001807 has_nsec = 1;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001808#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001809 ansec = mnsec = cnsec = 0;
Victor Stinnerccd57152012-02-08 14:31:50 +01001810 has_nsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001811#endif
Victor Stinnerccd57152012-02-08 14:31:50 +01001812 fill_time(v, 7, st->st_atime, ansec, has_nsec, timestamp);
1813 fill_time(v, 8, st->st_mtime, mnsec, has_nsec, timestamp);
1814 fill_time(v, 9, st->st_ctime, cnsec, has_nsec, timestamp);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001815
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001816#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001817 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1818 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001819#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001820#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001821 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1822 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001823#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001824#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001825 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1826 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001827#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001828#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1830 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001831#endif
1832#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001833 {
Victor Stinnerccd57152012-02-08 14:31:50 +01001834 PyObject *val;
1835 ts.seconds = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001836#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerccd57152012-02-08 14:31:50 +01001837 ts.numerator = st->st_birthtimespec.tv_nsec;
1838 ts.denominator = 1000000000;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001839#else
Victor Stinnerccd57152012-02-08 14:31:50 +01001840 ts.numerator = 0;
1841 ts.denominator = 1;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001842#endif
Victor Stinnerccd57152012-02-08 14:31:50 +01001843 if (timestamp == NULL) {
1844 if (_stat_float_times)
1845 val = _PyTime_Convert(&ts, (PyObject*)&PyFloat_Type);
1846 else
1847 val = _PyTime_Convert(&ts, (PyObject*)&PyLong_Type);
1848 }
1849 else {
1850 val = _PyTime_Convert(&ts, timestamp);
1851 }
1852 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1853 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00001854 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001855#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001856#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1858 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001859#endif
Fred Drake699f3522000-06-29 21:12:41 +00001860
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 if (PyErr_Occurred()) {
1862 Py_DECREF(v);
1863 return NULL;
1864 }
Fred Drake699f3522000-06-29 21:12:41 +00001865
Victor Stinner8c62be82010-05-06 00:08:46 +00001866 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001867}
1868
Barry Warsaw53699e91996-12-10 23:23:01 +00001869static PyObject *
Victor Stinnerccd57152012-02-08 14:31:50 +01001870posix_do_stat(PyObject *self, PyObject *args, PyObject *kw,
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001872#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001873 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001874#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001875 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001876#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001877 char *wformat,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001878 int (*wstatfunc)(const wchar_t *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001879{
Victor Stinnerccd57152012-02-08 14:31:50 +01001880 static char *kwlist[] = {"path", "timestamp", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +00001881 STRUCT_STAT st;
1882 PyObject *opath;
1883 char *path;
1884 int res;
1885 PyObject *result;
Victor Stinnerccd57152012-02-08 14:31:50 +01001886 PyObject *timestamp = NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001887
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001888#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001889 PyObject *po;
Victor Stinnerccd57152012-02-08 14:31:50 +01001890 if (PyArg_ParseTupleAndKeywords(args, kw, wformat, kwlist,
1891 &po, &timestamp)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001892 wchar_t *wpath = PyUnicode_AsUnicode(po);
1893 if (wpath == NULL)
1894 return NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00001895
Victor Stinner8c62be82010-05-06 00:08:46 +00001896 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 res = wstatfunc(wpath, &st);
1898 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001899
Victor Stinner8c62be82010-05-06 00:08:46 +00001900 if (res != 0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001901 return win32_error_object("stat", po);
Victor Stinnerccd57152012-02-08 14:31:50 +01001902 return _pystat_fromstructstat(&st, timestamp);
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 }
1904 /* Drop the argument parsing error as narrow strings
1905 are also valid. */
1906 PyErr_Clear();
Victor Stinnerccd57152012-02-08 14:31:50 +01001907 timestamp = NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001908#endif
1909
Victor Stinnerccd57152012-02-08 14:31:50 +01001910 if (!PyArg_ParseTupleAndKeywords(args, kw, format, kwlist,
1911 PyUnicode_FSConverter, &opath,
1912 &timestamp))
Victor Stinner8c62be82010-05-06 00:08:46 +00001913 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001914#ifdef MS_WINDOWS
1915 if (win32_warn_bytes_api()) {
1916 Py_DECREF(opath);
1917 return NULL;
1918 }
1919#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 path = PyBytes_AsString(opath);
1921 Py_BEGIN_ALLOW_THREADS
1922 res = (*statfunc)(path, &st);
1923 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001924
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001926#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001927 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001928#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001929 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001930#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 }
1932 else
Victor Stinnerccd57152012-02-08 14:31:50 +01001933 result = _pystat_fromstructstat(&st, timestamp);
Fred Drake699f3522000-06-29 21:12:41 +00001934
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 Py_DECREF(opath);
1936 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001937}
1938
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001939/* POSIX methods */
1940
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001941PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001942"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001943Use the real uid/gid to test for access to a path. Note that most\n\
1944operations will use the effective uid/gid, therefore this routine can\n\
1945be used in a suid/sgid environment to test if the invoking user has the\n\
1946specified access to the path. The mode argument can be F_OK to test\n\
1947existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001948
1949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001950posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001951{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001952 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001953 int mode;
1954
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001955#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02001957 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00001958 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02001959 wchar_t* wpath = PyUnicode_AsUnicode(po);
1960 if (wpath == NULL)
1961 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02001963 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00001964 Py_END_ALLOW_THREADS
1965 goto finish;
1966 }
1967 /* Drop the argument parsing error as narrow strings
1968 are also valid. */
1969 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001970 if (!PyArg_ParseTuple(args, "yi:access", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001972 if (win32_warn_bytes_api())
1973 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 Py_BEGIN_ALLOW_THREADS
1975 attr = GetFileAttributesA(path);
1976 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001977finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 if (attr == 0xFFFFFFFF)
1979 /* File does not exist, or cannot read attributes */
1980 return PyBool_FromLong(0);
1981 /* Access is possible if either write access wasn't requested, or
1982 the file isn't read-only, or if it's a directory, as there are
1983 no read-only directories on Windows. */
1984 return PyBool_FromLong(!(mode & 2)
1985 || !(attr & FILE_ATTRIBUTE_READONLY)
1986 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001987#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001988 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00001989 int res;
1990 if (!PyArg_ParseTuple(args, "O&i:access",
1991 PyUnicode_FSConverter, &opath, &mode))
1992 return NULL;
1993 path = PyBytes_AsString(opath);
1994 Py_BEGIN_ALLOW_THREADS
1995 res = access(path, mode);
1996 Py_END_ALLOW_THREADS
1997 Py_DECREF(opath);
1998 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001999#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002000}
2001
Guido van Rossumd371ff11999-01-25 16:12:23 +00002002#ifndef F_OK
2003#define F_OK 0
2004#endif
2005#ifndef R_OK
2006#define R_OK 4
2007#endif
2008#ifndef W_OK
2009#define W_OK 2
2010#endif
2011#ifndef X_OK
2012#define X_OK 1
2013#endif
2014
2015#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002016PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002017"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002018Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00002019
2020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002021posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002022{
Victor Stinner8c62be82010-05-06 00:08:46 +00002023 int id;
2024 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002025
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
2027 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002028
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002029#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002030 /* file descriptor 0 only, the default input device (stdin) */
2031 if (id == 0) {
2032 ret = ttyname();
2033 }
2034 else {
2035 ret = NULL;
2036 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002037#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002039#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 if (ret == NULL)
2041 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002042 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00002043}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002044#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002045
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002046#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002048"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002049Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002050
2051static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002052posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002053{
Victor Stinner8c62be82010-05-06 00:08:46 +00002054 char *ret;
2055 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002056
Greg Wardb48bc172000-03-01 21:51:56 +00002057#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002059#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002061#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 if (ret == NULL)
2063 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002064 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002065}
2066#endif
2067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002069"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002070Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002071
Barry Warsaw53699e91996-12-10 23:23:01 +00002072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002073posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002074{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002075#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002077#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002078 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00002079#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00002080 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002081#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002082 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002083#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002084}
2085
Fred Drake4d1e64b2002-04-15 19:40:07 +00002086#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002087PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002088"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00002089Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002090opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00002091
2092static PyObject *
2093posix_fchdir(PyObject *self, PyObject *fdobj)
2094{
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002096}
2097#endif /* HAVE_FCHDIR */
2098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002099
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002100PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002101"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002102Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002103
Barry Warsaw53699e91996-12-10 23:23:01 +00002104static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002105posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002106{
Victor Stinner8c62be82010-05-06 00:08:46 +00002107 PyObject *opath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002108 const char *path = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002109 int i;
2110 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002111#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002112 DWORD attr;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002113 PyObject *po;
Victor Stinner8c62be82010-05-06 00:08:46 +00002114 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002115 wchar_t *wpath = PyUnicode_AsUnicode(po);
2116 if (wpath == NULL)
2117 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002118 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02002119 attr = GetFileAttributesW(wpath);
Victor Stinner8c62be82010-05-06 00:08:46 +00002120 if (attr != 0xFFFFFFFF) {
2121 if (i & _S_IWRITE)
2122 attr &= ~FILE_ATTRIBUTE_READONLY;
2123 else
2124 attr |= FILE_ATTRIBUTE_READONLY;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002125 res = SetFileAttributesW(wpath, attr);
Victor Stinner8c62be82010-05-06 00:08:46 +00002126 }
2127 else
2128 res = 0;
2129 Py_END_ALLOW_THREADS
2130 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02002131 return win32_error_object("chmod", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 Py_INCREF(Py_None);
2133 return Py_None;
2134 }
2135 /* Drop the argument parsing error as narrow strings
2136 are also valid. */
2137 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002138
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002139 if (!PyArg_ParseTuple(args, "yi:chmod", &path, &i))
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002141 if (win32_warn_bytes_api())
2142 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002143 Py_BEGIN_ALLOW_THREADS
2144 attr = GetFileAttributesA(path);
2145 if (attr != 0xFFFFFFFF) {
2146 if (i & _S_IWRITE)
2147 attr &= ~FILE_ATTRIBUTE_READONLY;
2148 else
2149 attr |= FILE_ATTRIBUTE_READONLY;
2150 res = SetFileAttributesA(path, attr);
2151 }
2152 else
2153 res = 0;
2154 Py_END_ALLOW_THREADS
2155 if (!res) {
2156 win32_error("chmod", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00002157 return NULL;
2158 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002159 Py_INCREF(Py_None);
2160 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002161#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00002162 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
2163 &opath, &i))
2164 return NULL;
2165 path = PyBytes_AsString(opath);
2166 Py_BEGIN_ALLOW_THREADS
2167 res = chmod(path, i);
2168 Py_END_ALLOW_THREADS
2169 if (res < 0)
2170 return posix_error_with_allocated_filename(opath);
2171 Py_DECREF(opath);
2172 Py_INCREF(Py_None);
2173 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002174#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002175}
2176
Christian Heimes4e30a842007-11-30 22:12:06 +00002177#ifdef HAVE_FCHMOD
2178PyDoc_STRVAR(posix_fchmod__doc__,
2179"fchmod(fd, mode)\n\n\
2180Change the access permissions of the file given by file\n\
2181descriptor fd.");
2182
2183static PyObject *
2184posix_fchmod(PyObject *self, PyObject *args)
2185{
Victor Stinner8c62be82010-05-06 00:08:46 +00002186 int fd, mode, res;
2187 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
2188 return NULL;
2189 Py_BEGIN_ALLOW_THREADS
2190 res = fchmod(fd, mode);
2191 Py_END_ALLOW_THREADS
2192 if (res < 0)
2193 return posix_error();
2194 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002195}
2196#endif /* HAVE_FCHMOD */
2197
2198#ifdef HAVE_LCHMOD
2199PyDoc_STRVAR(posix_lchmod__doc__,
2200"lchmod(path, mode)\n\n\
2201Change the access permissions of a file. If path is a symlink, this\n\
2202affects the link itself rather than the target.");
2203
2204static PyObject *
2205posix_lchmod(PyObject *self, PyObject *args)
2206{
Victor Stinner8c62be82010-05-06 00:08:46 +00002207 PyObject *opath;
2208 char *path;
2209 int i;
2210 int res;
2211 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2212 &opath, &i))
2213 return NULL;
2214 path = PyBytes_AsString(opath);
2215 Py_BEGIN_ALLOW_THREADS
2216 res = lchmod(path, i);
2217 Py_END_ALLOW_THREADS
2218 if (res < 0)
2219 return posix_error_with_allocated_filename(opath);
2220 Py_DECREF(opath);
2221 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002222}
2223#endif /* HAVE_LCHMOD */
2224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002225
Thomas Wouterscf297e42007-02-23 15:07:44 +00002226#ifdef HAVE_CHFLAGS
2227PyDoc_STRVAR(posix_chflags__doc__,
2228"chflags(path, flags)\n\n\
2229Set file flags.");
2230
2231static PyObject *
2232posix_chflags(PyObject *self, PyObject *args)
2233{
Victor Stinner8c62be82010-05-06 00:08:46 +00002234 PyObject *opath;
2235 char *path;
2236 unsigned long flags;
2237 int res;
2238 if (!PyArg_ParseTuple(args, "O&k:chflags",
2239 PyUnicode_FSConverter, &opath, &flags))
2240 return NULL;
2241 path = PyBytes_AsString(opath);
2242 Py_BEGIN_ALLOW_THREADS
2243 res = chflags(path, flags);
2244 Py_END_ALLOW_THREADS
2245 if (res < 0)
2246 return posix_error_with_allocated_filename(opath);
2247 Py_DECREF(opath);
2248 Py_INCREF(Py_None);
2249 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002250}
2251#endif /* HAVE_CHFLAGS */
2252
2253#ifdef HAVE_LCHFLAGS
2254PyDoc_STRVAR(posix_lchflags__doc__,
2255"lchflags(path, flags)\n\n\
2256Set file flags.\n\
2257This function will not follow symbolic links.");
2258
2259static PyObject *
2260posix_lchflags(PyObject *self, PyObject *args)
2261{
Victor Stinner8c62be82010-05-06 00:08:46 +00002262 PyObject *opath;
2263 char *path;
2264 unsigned long flags;
2265 int res;
2266 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2267 PyUnicode_FSConverter, &opath, &flags))
2268 return NULL;
2269 path = PyBytes_AsString(opath);
2270 Py_BEGIN_ALLOW_THREADS
2271 res = lchflags(path, flags);
2272 Py_END_ALLOW_THREADS
2273 if (res < 0)
2274 return posix_error_with_allocated_filename(opath);
2275 Py_DECREF(opath);
2276 Py_INCREF(Py_None);
2277 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002278}
2279#endif /* HAVE_LCHFLAGS */
2280
Martin v. Löwis244edc82001-10-04 22:44:26 +00002281#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002282PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002283"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002284Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002285
2286static PyObject *
2287posix_chroot(PyObject *self, PyObject *args)
2288{
Victor Stinner8c62be82010-05-06 00:08:46 +00002289 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002290}
2291#endif
2292
Guido van Rossum21142a01999-01-08 21:05:37 +00002293#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002294PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002295"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002296force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002297
2298static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002299posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002300{
Stefan Krah0e803b32010-11-26 16:16:47 +00002301 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002302}
2303#endif /* HAVE_FSYNC */
2304
Ross Lagerwall7807c352011-03-17 20:20:30 +02002305#ifdef HAVE_SYNC
2306PyDoc_STRVAR(posix_sync__doc__,
2307"sync()\n\n\
2308Force write of everything to disk.");
2309
2310static PyObject *
2311posix_sync(PyObject *self, PyObject *noargs)
2312{
2313 Py_BEGIN_ALLOW_THREADS
2314 sync();
2315 Py_END_ALLOW_THREADS
2316 Py_RETURN_NONE;
2317}
2318#endif
2319
Guido van Rossum21142a01999-01-08 21:05:37 +00002320#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002321
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002322#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002323extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2324#endif
2325
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002326PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002327"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002328force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002329 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002330
2331static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002332posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002333{
Stefan Krah0e803b32010-11-26 16:16:47 +00002334 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002335}
2336#endif /* HAVE_FDATASYNC */
2337
2338
Fredrik Lundh10723342000-07-10 16:38:09 +00002339#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002340PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002341"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002342Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002343
Barry Warsaw53699e91996-12-10 23:23:01 +00002344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002345posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002346{
Victor Stinner8c62be82010-05-06 00:08:46 +00002347 PyObject *opath;
2348 char *path;
2349 long uid, gid;
2350 int res;
2351 if (!PyArg_ParseTuple(args, "O&ll:chown",
2352 PyUnicode_FSConverter, &opath,
2353 &uid, &gid))
2354 return NULL;
2355 path = PyBytes_AsString(opath);
2356 Py_BEGIN_ALLOW_THREADS
2357 res = chown(path, (uid_t) uid, (gid_t) gid);
2358 Py_END_ALLOW_THREADS
2359 if (res < 0)
2360 return posix_error_with_allocated_filename(opath);
2361 Py_DECREF(opath);
2362 Py_INCREF(Py_None);
2363 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002364}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002365#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002366
Christian Heimes4e30a842007-11-30 22:12:06 +00002367#ifdef HAVE_FCHOWN
2368PyDoc_STRVAR(posix_fchown__doc__,
2369"fchown(fd, uid, gid)\n\n\
2370Change the owner and group id of the file given by file descriptor\n\
2371fd to the numeric uid and gid.");
2372
2373static PyObject *
2374posix_fchown(PyObject *self, PyObject *args)
2375{
Victor Stinner8c62be82010-05-06 00:08:46 +00002376 int fd;
2377 long uid, gid;
2378 int res;
Victor Stinner26de69d2011-06-17 15:15:38 +02002379 if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00002380 return NULL;
2381 Py_BEGIN_ALLOW_THREADS
2382 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2383 Py_END_ALLOW_THREADS
2384 if (res < 0)
2385 return posix_error();
2386 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002387}
2388#endif /* HAVE_FCHOWN */
2389
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002390#ifdef HAVE_LCHOWN
2391PyDoc_STRVAR(posix_lchown__doc__,
2392"lchown(path, uid, gid)\n\n\
2393Change the owner and group id of path to the numeric uid and gid.\n\
2394This function will not follow symbolic links.");
2395
2396static PyObject *
2397posix_lchown(PyObject *self, PyObject *args)
2398{
Victor Stinner8c62be82010-05-06 00:08:46 +00002399 PyObject *opath;
2400 char *path;
2401 long uid, gid;
2402 int res;
2403 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2404 PyUnicode_FSConverter, &opath,
2405 &uid, &gid))
2406 return NULL;
2407 path = PyBytes_AsString(opath);
2408 Py_BEGIN_ALLOW_THREADS
2409 res = lchown(path, (uid_t) uid, (gid_t) gid);
2410 Py_END_ALLOW_THREADS
2411 if (res < 0)
2412 return posix_error_with_allocated_filename(opath);
2413 Py_DECREF(opath);
2414 Py_INCREF(Py_None);
2415 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002416}
2417#endif /* HAVE_LCHOWN */
2418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002419
Guido van Rossum36bc6801995-06-14 22:54:23 +00002420#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002421static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002422posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002423{
Victor Stinner8c62be82010-05-06 00:08:46 +00002424 char buf[1026];
2425 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002426
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002427#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002428 if (!use_bytes) {
2429 wchar_t wbuf[1026];
2430 wchar_t *wbuf2 = wbuf;
2431 PyObject *resobj;
2432 DWORD len;
2433 Py_BEGIN_ALLOW_THREADS
2434 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2435 /* If the buffer is large enough, len does not include the
2436 terminating \0. If the buffer is too small, len includes
2437 the space needed for the terminator. */
2438 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2439 wbuf2 = malloc(len * sizeof(wchar_t));
2440 if (wbuf2)
2441 len = GetCurrentDirectoryW(len, wbuf2);
2442 }
2443 Py_END_ALLOW_THREADS
2444 if (!wbuf2) {
2445 PyErr_NoMemory();
2446 return NULL;
2447 }
2448 if (!len) {
2449 if (wbuf2 != wbuf) free(wbuf2);
2450 return win32_error("getcwdu", NULL);
2451 }
2452 resobj = PyUnicode_FromWideChar(wbuf2, len);
2453 if (wbuf2 != wbuf) free(wbuf2);
2454 return resobj;
2455 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01002456
2457 if (win32_warn_bytes_api())
2458 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002459#endif
2460
Victor Stinner8c62be82010-05-06 00:08:46 +00002461 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002462#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002463 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002464#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002465 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002466#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002467 Py_END_ALLOW_THREADS
2468 if (res == NULL)
2469 return posix_error();
2470 if (use_bytes)
2471 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002472 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002473}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002474
2475PyDoc_STRVAR(posix_getcwd__doc__,
2476"getcwd() -> path\n\n\
2477Return a unicode string representing the current working directory.");
2478
2479static PyObject *
2480posix_getcwd_unicode(PyObject *self)
2481{
2482 return posix_getcwd(0);
2483}
2484
2485PyDoc_STRVAR(posix_getcwdb__doc__,
2486"getcwdb() -> path\n\n\
2487Return a bytes string representing the current working directory.");
2488
2489static PyObject *
2490posix_getcwd_bytes(PyObject *self)
2491{
2492 return posix_getcwd(1);
2493}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002494#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002496
Guido van Rossumb6775db1994-08-01 11:34:53 +00002497#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002498PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002499"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002500Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002501
Barry Warsaw53699e91996-12-10 23:23:01 +00002502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002503posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002504{
Victor Stinner8c62be82010-05-06 00:08:46 +00002505 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002506}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002507#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002508
Brian Curtin1b9df392010-11-24 20:24:31 +00002509#ifdef MS_WINDOWS
2510PyDoc_STRVAR(win32_link__doc__,
2511"link(src, dst)\n\n\
2512Create a hard link to a file.");
2513
2514static PyObject *
2515win32_link(PyObject *self, PyObject *args)
2516{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002517 PyObject *src, *dst;
2518 BOOL ok;
Brian Curtin1b9df392010-11-24 20:24:31 +00002519
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002520 if (PyArg_ParseTuple(args, "UU:link", &src, &dst))
Victor Stinnereb5657a2011-09-30 01:44:27 +02002521 {
2522 wchar_t *wsrc, *wdst;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002523
2524 wsrc = PyUnicode_AsUnicode(src);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002525 if (wsrc == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002526 goto error;
2527 wdst = PyUnicode_AsUnicode(dst);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002528 if (wdst == NULL)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002529 goto error;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002530
Brian Curtinfc889c42010-11-28 23:59:46 +00002531 Py_BEGIN_ALLOW_THREADS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002532 ok = CreateHardLinkW(wdst, wsrc, NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002533 Py_END_ALLOW_THREADS
2534
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002535 if (!ok)
Brian Curtinfc889c42010-11-28 23:59:46 +00002536 return win32_error("link", NULL);
Brian Curtinfc889c42010-11-28 23:59:46 +00002537 Py_RETURN_NONE;
2538 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002539 else {
2540 PyErr_Clear();
2541 if (!PyArg_ParseTuple(args, "O&O&:link",
2542 PyUnicode_FSConverter, &src,
2543 PyUnicode_FSConverter, &dst))
2544 return NULL;
Brian Curtinfc889c42010-11-28 23:59:46 +00002545
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002546 if (win32_warn_bytes_api())
2547 goto error;
Brian Curtinfc889c42010-11-28 23:59:46 +00002548
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002549 Py_BEGIN_ALLOW_THREADS
2550 ok = CreateHardLinkA(PyBytes_AS_STRING(dst),
2551 PyBytes_AS_STRING(src),
2552 NULL);
2553 Py_END_ALLOW_THREADS
2554
2555 Py_XDECREF(src);
2556 Py_XDECREF(dst);
2557
2558 if (!ok)
2559 return win32_error("link", NULL);
2560 Py_RETURN_NONE;
2561
2562 error:
2563 Py_XDECREF(src);
2564 Py_XDECREF(dst);
Brian Curtin1b9df392010-11-24 20:24:31 +00002565 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002566 }
Brian Curtin1b9df392010-11-24 20:24:31 +00002567}
2568#endif /* MS_WINDOWS */
2569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002571PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002572"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002573Return a list containing the names of the entries in the directory.\n\
2574\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002575 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002576\n\
2577The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002578entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002579
Barry Warsaw53699e91996-12-10 23:23:01 +00002580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002581posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002582{
Victor Stinner8c62be82010-05-06 00:08:46 +00002583 /* XXX Should redo this putting the (now four) versions of opendir
2584 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002585#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002586
Victor Stinner8c62be82010-05-06 00:08:46 +00002587 PyObject *d, *v;
2588 HANDLE hFindFile;
2589 BOOL result;
2590 WIN32_FIND_DATA FileData;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002591 const char *path;
2592 Py_ssize_t pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002593 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2594 char *bufptr = namebuf;
2595 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002596
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002597 PyObject *po = NULL;
2598 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002599 WIN32_FIND_DATAW wFileData;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002600 wchar_t *wnamebuf, *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00002601
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002602 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002603 po_wchars = L".";
2604 len = 1;
2605 } else {
Victor Stinnerbeac78b2011-10-11 21:55:01 +02002606 po_wchars = PyUnicode_AsUnicodeAndSize(po, &len);
Victor Stinnereb5657a2011-09-30 01:44:27 +02002607 if (po_wchars == NULL)
2608 return NULL;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002609 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002610 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002611 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2612 if (!wnamebuf) {
2613 PyErr_NoMemory();
2614 return NULL;
2615 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002616 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002617 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02002618 wchar_t wch = wnamebuf[len-1];
Victor Stinner8c62be82010-05-06 00:08:46 +00002619 if (wch != L'/' && wch != L'\\' && wch != L':')
2620 wnamebuf[len++] = L'\\';
2621 wcscpy(wnamebuf + len, L"*.*");
2622 }
2623 if ((d = PyList_New(0)) == NULL) {
2624 free(wnamebuf);
2625 return NULL;
2626 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002627 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002628 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002629 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002630 if (hFindFile == INVALID_HANDLE_VALUE) {
2631 int error = GetLastError();
2632 if (error == ERROR_FILE_NOT_FOUND) {
2633 free(wnamebuf);
2634 return d;
2635 }
2636 Py_DECREF(d);
2637 win32_error_unicode("FindFirstFileW", wnamebuf);
2638 free(wnamebuf);
2639 return NULL;
2640 }
2641 do {
2642 /* Skip over . and .. */
2643 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2644 wcscmp(wFileData.cFileName, L"..") != 0) {
Victor Stinner9d3b93b2011-11-22 02:27:30 +01002645 v = PyUnicode_FromWideChar(wFileData.cFileName, wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00002646 if (v == NULL) {
2647 Py_DECREF(d);
2648 d = NULL;
2649 break;
2650 }
2651 if (PyList_Append(d, v) != 0) {
2652 Py_DECREF(v);
2653 Py_DECREF(d);
2654 d = NULL;
2655 break;
2656 }
2657 Py_DECREF(v);
2658 }
2659 Py_BEGIN_ALLOW_THREADS
2660 result = FindNextFileW(hFindFile, &wFileData);
2661 Py_END_ALLOW_THREADS
2662 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2663 it got to the end of the directory. */
2664 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2665 Py_DECREF(d);
2666 win32_error_unicode("FindNextFileW", wnamebuf);
2667 FindClose(hFindFile);
2668 free(wnamebuf);
2669 return NULL;
2670 }
2671 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002672
Victor Stinner8c62be82010-05-06 00:08:46 +00002673 if (FindClose(hFindFile) == FALSE) {
2674 Py_DECREF(d);
2675 win32_error_unicode("FindClose", wnamebuf);
2676 free(wnamebuf);
2677 return NULL;
2678 }
2679 free(wnamebuf);
2680 return d;
2681 }
2682 /* Drop the argument parsing error as narrow strings
2683 are also valid. */
2684 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002685
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002686 if (!PyArg_ParseTuple(args, "y#:listdir", &path, &pathlen))
Victor Stinner8c62be82010-05-06 00:08:46 +00002687 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002688 if (win32_warn_bytes_api())
2689 return NULL;
2690 if (pathlen+1 > MAX_PATH) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002691 PyErr_SetString(PyExc_ValueError, "path too long");
Victor Stinner8c62be82010-05-06 00:08:46 +00002692 return NULL;
2693 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002694 strcpy(namebuf, path);
2695 len = pathlen;
Victor Stinner8c62be82010-05-06 00:08:46 +00002696 if (len > 0) {
2697 char ch = namebuf[len-1];
2698 if (ch != SEP && ch != ALTSEP && ch != ':')
2699 namebuf[len++] = '/';
2700 strcpy(namebuf + len, "*.*");
2701 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002702
Victor Stinner8c62be82010-05-06 00:08:46 +00002703 if ((d = PyList_New(0)) == NULL)
2704 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002705
Antoine Pitroub73caab2010-08-09 23:39:31 +00002706 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002707 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002708 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002709 if (hFindFile == INVALID_HANDLE_VALUE) {
2710 int error = GetLastError();
2711 if (error == ERROR_FILE_NOT_FOUND)
2712 return d;
2713 Py_DECREF(d);
2714 return win32_error("FindFirstFile", namebuf);
2715 }
2716 do {
2717 /* Skip over . and .. */
2718 if (strcmp(FileData.cFileName, ".") != 0 &&
2719 strcmp(FileData.cFileName, "..") != 0) {
2720 v = PyBytes_FromString(FileData.cFileName);
2721 if (v == NULL) {
2722 Py_DECREF(d);
2723 d = NULL;
2724 break;
2725 }
2726 if (PyList_Append(d, v) != 0) {
2727 Py_DECREF(v);
2728 Py_DECREF(d);
2729 d = NULL;
2730 break;
2731 }
2732 Py_DECREF(v);
2733 }
2734 Py_BEGIN_ALLOW_THREADS
2735 result = FindNextFile(hFindFile, &FileData);
2736 Py_END_ALLOW_THREADS
2737 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2738 it got to the end of the directory. */
2739 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2740 Py_DECREF(d);
2741 win32_error("FindNextFile", namebuf);
2742 FindClose(hFindFile);
2743 return NULL;
2744 }
2745 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002746
Victor Stinner8c62be82010-05-06 00:08:46 +00002747 if (FindClose(hFindFile) == FALSE) {
2748 Py_DECREF(d);
2749 return win32_error("FindClose", namebuf);
2750 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002751
Victor Stinner8c62be82010-05-06 00:08:46 +00002752 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002753
Tim Peters0bb44a42000-09-15 07:44:49 +00002754#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002755
2756#ifndef MAX_PATH
2757#define MAX_PATH CCHMAXPATH
2758#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002759 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002760 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002761 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002762 PyObject *d, *v;
2763 char namebuf[MAX_PATH+5];
2764 HDIR hdir = 1;
2765 ULONG srchcnt = 1;
2766 FILEFINDBUF3 ep;
2767 APIRET rc;
2768
Victor Stinner8c62be82010-05-06 00:08:46 +00002769 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002770 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002771 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002772 name = PyBytes_AsString(oname);
2773 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002774 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002775 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002776 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002777 return NULL;
2778 }
2779 strcpy(namebuf, name);
2780 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002781 if (*pt == ALTSEP)
2782 *pt = SEP;
2783 if (namebuf[len-1] != SEP)
2784 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002785 strcpy(namebuf + len, "*.*");
2786
Neal Norwitz6c913782007-10-14 03:23:09 +00002787 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002788 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002789 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002790 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002791
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002792 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2793 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002794 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002795 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2796 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2797 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002798
2799 if (rc != NO_ERROR) {
2800 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002801 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002802 }
2803
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002804 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002805 do {
2806 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002807 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002808 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002809
2810 strcpy(namebuf, ep.achName);
2811
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002812 /* Leave Case of Name Alone -- In Native Form */
2813 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002814
Christian Heimes72b710a2008-05-26 13:28:38 +00002815 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002816 if (v == NULL) {
2817 Py_DECREF(d);
2818 d = NULL;
2819 break;
2820 }
2821 if (PyList_Append(d, v) != 0) {
2822 Py_DECREF(v);
2823 Py_DECREF(d);
2824 d = NULL;
2825 break;
2826 }
2827 Py_DECREF(v);
2828 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2829 }
2830
Victor Stinnerdcb24032010-04-22 12:08:36 +00002831 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002832 return d;
2833#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002834 PyObject *oname;
2835 char *name;
2836 PyObject *d, *v;
2837 DIR *dirp;
2838 struct dirent *ep;
2839 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002840
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002842 /* v is never read, so it does not need to be initialized yet. */
2843 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002844 arg_is_unicode = 0;
2845 PyErr_Clear();
2846 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002847 oname = NULL;
2848 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002850 if (oname == NULL) { /* Default arg: "." */
Stefan Krah0e803b32010-11-26 16:16:47 +00002851 oname = PyBytes_FromString(".");
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002852 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002854 Py_BEGIN_ALLOW_THREADS
2855 dirp = opendir(name);
2856 Py_END_ALLOW_THREADS
2857 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002858 return posix_error_with_allocated_filename(oname);
2859 }
2860 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002861 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002862 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002863 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002864 Py_DECREF(oname);
2865 return NULL;
2866 }
2867 for (;;) {
2868 errno = 0;
2869 Py_BEGIN_ALLOW_THREADS
2870 ep = readdir(dirp);
2871 Py_END_ALLOW_THREADS
2872 if (ep == NULL) {
2873 if (errno == 0) {
2874 break;
2875 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002876 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002877 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002878 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002879 Py_DECREF(d);
2880 return posix_error_with_allocated_filename(oname);
2881 }
2882 }
2883 if (ep->d_name[0] == '.' &&
2884 (NAMLEN(ep) == 1 ||
2885 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2886 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002887 if (arg_is_unicode)
2888 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2889 else
2890 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002891 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002892 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 break;
2894 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002895 if (PyList_Append(d, v) != 0) {
2896 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002897 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002898 break;
2899 }
2900 Py_DECREF(v);
2901 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002902 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002904 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002906
Victor Stinner8c62be82010-05-06 00:08:46 +00002907 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002908
Tim Peters0bb44a42000-09-15 07:44:49 +00002909#endif /* which OS */
2910} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002911
Antoine Pitrou8250e232011-02-25 23:41:16 +00002912#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +01002913PyDoc_STRVAR(posix_flistdir__doc__,
2914"flistdir(fd) -> list_of_strings\n\n\
Charles-François Natali76961fa2012-01-10 20:25:09 +01002915Like listdir(), but uses a file descriptor instead.");
Antoine Pitrou8250e232011-02-25 23:41:16 +00002916
2917static PyObject *
Charles-François Natali77940902012-02-06 19:54:48 +01002918posix_flistdir(PyObject *self, PyObject *args)
Antoine Pitrou8250e232011-02-25 23:41:16 +00002919{
2920 PyObject *d, *v;
2921 DIR *dirp;
2922 struct dirent *ep;
2923 int fd;
2924
2925 errno = 0;
Charles-François Natali77940902012-02-06 19:54:48 +01002926 if (!PyArg_ParseTuple(args, "i:flistdir", &fd))
Antoine Pitrou8250e232011-02-25 23:41:16 +00002927 return NULL;
Charles-François Natali76961fa2012-01-10 20:25:09 +01002928 /* closedir() closes the FD, so we duplicate it */
2929 fd = dup(fd);
2930 if (fd < 0)
2931 return posix_error();
Antoine Pitrou8250e232011-02-25 23:41:16 +00002932 Py_BEGIN_ALLOW_THREADS
2933 dirp = fdopendir(fd);
2934 Py_END_ALLOW_THREADS
2935 if (dirp == NULL) {
2936 close(fd);
2937 return posix_error();
2938 }
2939 if ((d = PyList_New(0)) == NULL) {
2940 Py_BEGIN_ALLOW_THREADS
2941 closedir(dirp);
2942 Py_END_ALLOW_THREADS
2943 return NULL;
2944 }
2945 for (;;) {
2946 errno = 0;
2947 Py_BEGIN_ALLOW_THREADS
2948 ep = readdir(dirp);
2949 Py_END_ALLOW_THREADS
2950 if (ep == NULL) {
2951 if (errno == 0) {
2952 break;
2953 } else {
2954 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002955 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002956 closedir(dirp);
2957 Py_END_ALLOW_THREADS
2958 Py_DECREF(d);
2959 return posix_error();
2960 }
2961 }
2962 if (ep->d_name[0] == '.' &&
2963 (NAMLEN(ep) == 1 ||
2964 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2965 continue;
2966 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2967 if (v == NULL) {
2968 Py_CLEAR(d);
2969 break;
2970 }
2971 if (PyList_Append(d, v) != 0) {
2972 Py_DECREF(v);
2973 Py_CLEAR(d);
2974 break;
2975 }
2976 Py_DECREF(v);
2977 }
2978 Py_BEGIN_ALLOW_THREADS
Charles-François Natalif2840a82012-01-08 20:30:47 +01002979 rewinddir(dirp);
Antoine Pitrou8250e232011-02-25 23:41:16 +00002980 closedir(dirp);
2981 Py_END_ALLOW_THREADS
2982
2983 return d;
2984}
2985#endif
2986
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002987#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002988/* A helper function for abspath on win32 */
2989static PyObject *
2990posix__getfullpathname(PyObject *self, PyObject *args)
2991{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01002992 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 char outbuf[MAX_PATH*2];
2994 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02002995 PyObject *po;
2996
2997 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
2998 {
2999 wchar_t *wpath;
3000 wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
3001 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003002 DWORD result;
3003 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003004
3005 wpath = PyUnicode_AsUnicode(po);
3006 if (wpath == NULL)
3007 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003008 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003009 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003010 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003011 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003012 woutbufp = malloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 if (!woutbufp)
3014 return PyErr_NoMemory();
3015 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3016 }
3017 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003018 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003019 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003020 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003021 if (woutbufp != woutbuf)
3022 free(woutbufp);
3023 return v;
3024 }
3025 /* Drop the argument parsing error as narrow strings
3026 are also valid. */
3027 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003028
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003029 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3030 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003031 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003032 if (win32_warn_bytes_api())
3033 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003034 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003035 outbuf, &temp)) {
3036 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003037 return NULL;
3038 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003039 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3040 return PyUnicode_Decode(outbuf, strlen(outbuf),
3041 Py_FileSystemDefaultEncoding, NULL);
3042 }
3043 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00003044} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00003045
Brian Curtind25aef52011-06-13 15:16:04 -05003046
Brian Curtinf5e76d02010-11-24 13:14:05 +00003047
Brian Curtind40e6f72010-07-08 21:39:08 +00003048/* A helper function for samepath on windows */
3049static PyObject *
3050posix__getfinalpathname(PyObject *self, PyObject *args)
3051{
3052 HANDLE hFile;
3053 int buf_size;
3054 wchar_t *target_path;
3055 int result_length;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003056 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00003057 wchar_t *path;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003058
Victor Stinnereb5657a2011-09-30 01:44:27 +02003059 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
Brian Curtind40e6f72010-07-08 21:39:08 +00003060 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003061 path = PyUnicode_AsUnicode(po);
3062 if (path == NULL)
3063 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003064
3065 if(!check_GetFinalPathNameByHandle()) {
3066 /* If the OS doesn't have GetFinalPathNameByHandle, return a
3067 NotImplementedError. */
3068 return PyErr_Format(PyExc_NotImplementedError,
3069 "GetFinalPathNameByHandle not available on this platform");
3070 }
3071
3072 hFile = CreateFileW(
3073 path,
3074 0, /* desired access */
3075 0, /* share mode */
3076 NULL, /* security attributes */
3077 OPEN_EXISTING,
3078 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3079 FILE_FLAG_BACKUP_SEMANTICS,
3080 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003081
Victor Stinnereb5657a2011-09-30 01:44:27 +02003082 if(hFile == INVALID_HANDLE_VALUE)
3083 return win32_error_object("CreateFileW", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003084
3085 /* We have a good handle to the target, use it to determine the
3086 target path name. */
3087 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3088
3089 if(!buf_size)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003090 return win32_error_object("GetFinalPathNameByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003091
3092 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
3093 if(!target_path)
3094 return PyErr_NoMemory();
3095
3096 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
3097 buf_size, VOLUME_NAME_DOS);
3098 if(!result_length)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003099 return win32_error_object("GetFinalPathNamyByHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003100
3101 if(!CloseHandle(hFile))
Victor Stinnereb5657a2011-09-30 01:44:27 +02003102 return win32_error_object("CloseHandle", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00003103
3104 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003105 result = PyUnicode_FromWideChar(target_path, result_length);
Brian Curtind40e6f72010-07-08 21:39:08 +00003106 free(target_path);
3107 return result;
3108
3109} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00003110
3111static PyObject *
3112posix__getfileinformation(PyObject *self, PyObject *args)
3113{
3114 HANDLE hFile;
3115 BY_HANDLE_FILE_INFORMATION info;
3116 int fd;
3117
3118 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
3119 return NULL;
3120
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003121 if (!_PyVerify_fd(fd))
3122 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003123
3124 hFile = (HANDLE)_get_osfhandle(fd);
3125 if (hFile == INVALID_HANDLE_VALUE)
Hirokazu Yamamoto26253bb2010-12-05 04:16:47 +00003126 return posix_error();
Brian Curtin62857742010-09-06 17:07:27 +00003127
3128 if (!GetFileInformationByHandle(hFile, &info))
3129 return win32_error("_getfileinformation", NULL);
3130
3131 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
3132 info.nFileIndexHigh,
3133 info.nFileIndexLow);
3134}
Brian Curtin9c669cc2011-06-08 18:17:18 -05003135
Brian Curtin95d028f2011-06-09 09:10:38 -05003136PyDoc_STRVAR(posix__isdir__doc__,
3137"Return true if the pathname refers to an existing directory.");
3138
Brian Curtin9c669cc2011-06-08 18:17:18 -05003139static PyObject *
3140posix__isdir(PyObject *self, PyObject *args)
3141{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003142 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003143 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003144 DWORD attributes;
3145
3146 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003147 wchar_t *wpath = PyUnicode_AsUnicode(po);
3148 if (wpath == NULL)
3149 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003150
3151 attributes = GetFileAttributesW(wpath);
3152 if (attributes == INVALID_FILE_ATTRIBUTES)
3153 Py_RETURN_FALSE;
3154 goto check;
3155 }
3156 /* Drop the argument parsing error as narrow strings
3157 are also valid. */
3158 PyErr_Clear();
3159
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003160 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003161 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003162 if (win32_warn_bytes_api())
3163 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003164 attributes = GetFileAttributesA(path);
3165 if (attributes == INVALID_FILE_ATTRIBUTES)
3166 Py_RETURN_FALSE;
3167
3168check:
3169 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3170 Py_RETURN_TRUE;
3171 else
3172 Py_RETURN_FALSE;
3173}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003174#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003175
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003176PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003177"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003178Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003179
Barry Warsaw53699e91996-12-10 23:23:01 +00003180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003181posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003182{
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 int res;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003184 const char *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00003185 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003186
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003187#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003188 PyObject *po;
3189 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode))
3190 {
3191 wchar_t *wpath = PyUnicode_AsUnicode(po);
3192 if (wpath == NULL)
3193 return NULL;
3194
Victor Stinner8c62be82010-05-06 00:08:46 +00003195 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02003196 res = CreateDirectoryW(wpath, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 Py_END_ALLOW_THREADS
3198 if (!res)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003199 return win32_error_object("mkdir", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003200 Py_INCREF(Py_None);
3201 return Py_None;
3202 }
3203 /* Drop the argument parsing error as narrow strings
3204 are also valid. */
3205 PyErr_Clear();
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003206 if (!PyArg_ParseTuple(args, "y|i:mkdir", &path, &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00003207 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003208 if (win32_warn_bytes_api())
3209 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003210 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 res = CreateDirectoryA(path, NULL);
3212 Py_END_ALLOW_THREADS
3213 if (!res) {
3214 win32_error("mkdir", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003215 return NULL;
3216 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003217 Py_INCREF(Py_None);
3218 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003219#else
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003220 PyObject *opath;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003221
Victor Stinner8c62be82010-05-06 00:08:46 +00003222 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
3223 PyUnicode_FSConverter, &opath, &mode))
3224 return NULL;
3225 path = PyBytes_AsString(opath);
3226 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00003227#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00003228 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003229#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003231#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 Py_END_ALLOW_THREADS
3233 if (res < 0)
3234 return posix_error_with_allocated_filename(opath);
3235 Py_DECREF(opath);
3236 Py_INCREF(Py_None);
3237 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003238#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003239}
3240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003241
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003242/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3243#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003244#include <sys/resource.h>
3245#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003246
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003247
3248#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003249PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003250"nice(inc) -> new_priority\n\n\
3251Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003252
Barry Warsaw53699e91996-12-10 23:23:01 +00003253static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003254posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00003255{
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00003257
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 if (!PyArg_ParseTuple(args, "i:nice", &increment))
3259 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003260
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 /* There are two flavours of 'nice': one that returns the new
3262 priority (as required by almost all standards out there) and the
3263 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3264 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003265
Victor Stinner8c62be82010-05-06 00:08:46 +00003266 If we are of the nice family that returns the new priority, we
3267 need to clear errno before the call, and check if errno is filled
3268 before calling posix_error() on a returnvalue of -1, because the
3269 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003270
Victor Stinner8c62be82010-05-06 00:08:46 +00003271 errno = 0;
3272 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003273#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003274 if (value == 0)
3275 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003276#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003277 if (value == -1 && errno != 0)
3278 /* either nice() or getpriority() returned an error */
3279 return posix_error();
3280 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003281}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003282#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003283
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003284
3285#ifdef HAVE_GETPRIORITY
3286PyDoc_STRVAR(posix_getpriority__doc__,
3287"getpriority(which, who) -> current_priority\n\n\
3288Get program scheduling priority.");
3289
3290static PyObject *
3291posix_getpriority(PyObject *self, PyObject *args)
3292{
3293 int which, who, retval;
3294
3295 if (!PyArg_ParseTuple(args, "ii", &which, &who))
3296 return NULL;
3297 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003298 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003299 if (errno != 0)
3300 return posix_error();
3301 return PyLong_FromLong((long)retval);
3302}
3303#endif /* HAVE_GETPRIORITY */
3304
3305
3306#ifdef HAVE_SETPRIORITY
3307PyDoc_STRVAR(posix_setpriority__doc__,
3308"setpriority(which, who, prio) -> None\n\n\
3309Set program scheduling priority.");
3310
3311static PyObject *
3312posix_setpriority(PyObject *self, PyObject *args)
3313{
3314 int which, who, prio, retval;
3315
3316 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio))
3317 return NULL;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003318 retval = setpriority(which, who, prio);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003319 if (retval == -1)
3320 return posix_error();
3321 Py_RETURN_NONE;
3322}
3323#endif /* HAVE_SETPRIORITY */
3324
3325
Barry Warsaw53699e91996-12-10 23:23:01 +00003326static PyObject *
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003327internal_rename(PyObject *self, PyObject *args, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003328{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003329#ifdef MS_WINDOWS
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003330 PyObject *src, *dst;
Victor Stinner8c62be82010-05-06 00:08:46 +00003331 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003332 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
3333 if (PyArg_ParseTuple(args,
3334 is_replace ? "UU:replace" : "UU:rename",
3335 &src, &dst))
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003336 {
3337 wchar_t *wsrc, *wdst;
3338
3339 wsrc = PyUnicode_AsUnicode(src);
3340 if (wsrc == NULL)
3341 return NULL;
3342 wdst = PyUnicode_AsUnicode(dst);
3343 if (wdst == NULL)
3344 return NULL;
3345 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003346 result = MoveFileExW(wsrc, wdst, flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003347 Py_END_ALLOW_THREADS
3348 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003349 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003350 Py_INCREF(Py_None);
3351 return Py_None;
Victor Stinner8c62be82010-05-06 00:08:46 +00003352 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003353 else {
3354 PyErr_Clear();
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003355 if (!PyArg_ParseTuple(args,
3356 is_replace ? "O&O&:replace" : "O&O&:rename",
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003357 PyUnicode_FSConverter, &src,
3358 PyUnicode_FSConverter, &dst))
3359 return NULL;
3360
3361 if (win32_warn_bytes_api())
3362 goto error;
3363
3364 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003365 result = MoveFileExA(PyBytes_AS_STRING(src),
3366 PyBytes_AS_STRING(dst), flags);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003367 Py_END_ALLOW_THREADS
3368
3369 Py_XDECREF(src);
3370 Py_XDECREF(dst);
3371
3372 if (!result)
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003373 return win32_error(is_replace ? "replace" : "rename", NULL);
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003374 Py_INCREF(Py_None);
3375 return Py_None;
3376
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003377error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003378 Py_XDECREF(src);
3379 Py_XDECREF(dst);
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003381 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003382#else
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003383 return posix_2str(args,
3384 is_replace ? "O&O&:replace" : "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003385#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003386}
3387
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003388PyDoc_STRVAR(posix_rename__doc__,
3389"rename(old, new)\n\n\
3390Rename a file or directory.");
3391
3392static PyObject *
3393posix_rename(PyObject *self, PyObject *args)
3394{
3395 return internal_rename(self, args, 0);
3396}
3397
3398PyDoc_STRVAR(posix_replace__doc__,
3399"replace(old, new)\n\n\
3400Rename a file or directory, overwriting the destination.");
3401
3402static PyObject *
3403posix_replace(PyObject *self, PyObject *args)
3404{
3405 return internal_rename(self, args, 1);
3406}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003407
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003408PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003409"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003410Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003411
Barry Warsaw53699e91996-12-10 23:23:01 +00003412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003413posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003414{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003415#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003417#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003419#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003420}
3421
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003422
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003423PyDoc_STRVAR(posix_stat__doc__,
Victor Stinnerccd57152012-02-08 14:31:50 +01003424"stat(path, timestamp=None) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003425Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003426
Barry Warsaw53699e91996-12-10 23:23:01 +00003427static PyObject *
Victor Stinnerccd57152012-02-08 14:31:50 +01003428posix_stat(PyObject *self, PyObject *args, PyObject *kw)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003429{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003430#ifdef MS_WINDOWS
Victor Stinnerccd57152012-02-08 14:31:50 +01003431 return posix_do_stat(self, args, kw, "O&|O:stat", STAT, "U|O:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003432#else
Victor Stinnerccd57152012-02-08 14:31:50 +01003433 return posix_do_stat(self, args, kw, "O&|O:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003434#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003435}
3436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003437
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003438#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003439PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003440"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003441Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003442
Barry Warsaw53699e91996-12-10 23:23:01 +00003443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003444posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003445{
Victor Stinner8c62be82010-05-06 00:08:46 +00003446 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00003447#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003448 wchar_t *command;
3449 if (!PyArg_ParseTuple(args, "u:system", &command))
3450 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003451
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 Py_BEGIN_ALLOW_THREADS
3453 sts = _wsystem(command);
3454 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00003455#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 PyObject *command_obj;
3457 char *command;
3458 if (!PyArg_ParseTuple(args, "O&:system",
3459 PyUnicode_FSConverter, &command_obj))
3460 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00003461
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 command = PyBytes_AsString(command_obj);
3463 Py_BEGIN_ALLOW_THREADS
3464 sts = system(command);
3465 Py_END_ALLOW_THREADS
3466 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003467#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003469}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003470#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003472
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003473PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003474"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003475Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003476
Barry Warsaw53699e91996-12-10 23:23:01 +00003477static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003478posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003479{
Victor Stinner8c62be82010-05-06 00:08:46 +00003480 int i;
3481 if (!PyArg_ParseTuple(args, "i:umask", &i))
3482 return NULL;
3483 i = (int)umask(i);
3484 if (i < 0)
3485 return posix_error();
3486 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003487}
3488
Brian Curtind40e6f72010-07-08 21:39:08 +00003489#ifdef MS_WINDOWS
3490
3491/* override the default DeleteFileW behavior so that directory
3492symlinks can be removed with this function, the same as with
3493Unix symlinks */
3494BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3495{
3496 WIN32_FILE_ATTRIBUTE_DATA info;
3497 WIN32_FIND_DATAW find_data;
3498 HANDLE find_data_handle;
3499 int is_directory = 0;
3500 int is_link = 0;
3501
3502 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3503 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003504
Brian Curtind40e6f72010-07-08 21:39:08 +00003505 /* Get WIN32_FIND_DATA structure for the path to determine if
3506 it is a symlink */
3507 if(is_directory &&
3508 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3509 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3510
3511 if(find_data_handle != INVALID_HANDLE_VALUE) {
3512 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3513 FindClose(find_data_handle);
3514 }
3515 }
3516 }
3517
3518 if (is_directory && is_link)
3519 return RemoveDirectoryW(lpFileName);
3520
3521 return DeleteFileW(lpFileName);
3522}
3523#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003525PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003526"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003527Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003529PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003530"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003531Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003532
Barry Warsaw53699e91996-12-10 23:23:01 +00003533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003534posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003535{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003536#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003537 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3538 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003539#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003541#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003542}
3543
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003544
Guido van Rossumb6775db1994-08-01 11:34:53 +00003545#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003546PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003547"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003548Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003549
Barry Warsaw53699e91996-12-10 23:23:01 +00003550static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003551posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003552{
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 struct utsname u;
3554 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003555
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 Py_BEGIN_ALLOW_THREADS
3557 res = uname(&u);
3558 Py_END_ALLOW_THREADS
3559 if (res < 0)
3560 return posix_error();
3561 return Py_BuildValue("(sssss)",
3562 u.sysname,
3563 u.nodename,
3564 u.release,
3565 u.version,
3566 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003567}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003568#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003569
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003570
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003571static int
Victor Stinnera2f7c002012-02-08 03:36:25 +01003572extract_time(PyObject *t, time_t* sec, long* nsec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003573{
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003574 time_t intval;
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 if (PyFloat_Check(t)) {
Victor Stinnera2f7c002012-02-08 03:36:25 +01003576 double d = PyFloat_AsDouble(t);
3577 double mod;
3578 *sec = (time_t)d;
3579 mod = fmod(d, 1.0);
3580 mod *= 1e9;
3581 *nsec = (long)mod;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003582 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003583 }
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003584#if SIZEOF_TIME_T > SIZEOF_LONG
3585 intval = PyLong_AsUnsignedLongLongMask(t);
3586#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 intval = PyLong_AsLong(t);
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003588#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 if (intval == -1 && PyErr_Occurred())
3590 return -1;
3591 *sec = intval;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003592 *nsec = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003594}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003595
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003596PyDoc_STRVAR(posix_utime__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003597"utime(path[, (atime, mtime)])\n\
3598Set the access and modified time of the file to the given values.\n\
3599If no second argument is used, set the access and modified times to\n\
3600the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003601
Barry Warsaw53699e91996-12-10 23:23:01 +00003602static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003603posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003604{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003605#ifdef MS_WINDOWS
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003606 PyObject *arg = Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003607 PyObject *obwpath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003608 wchar_t *wpath = NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003609 const char *apath;
Victor Stinner8c62be82010-05-06 00:08:46 +00003610 HANDLE hFile;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003611 time_t atimesec, mtimesec;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003612 long ansec, mnsec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 FILETIME atime, mtime;
3614 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003615
Brian Curtin52fbea12011-11-06 13:41:17 -06003616 if (PyArg_ParseTuple(args, "U|O:utime", &obwpath, &arg)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003617 wpath = PyUnicode_AsUnicode(obwpath);
3618 if (wpath == NULL)
3619 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 Py_BEGIN_ALLOW_THREADS
3621 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3622 NULL, OPEN_EXISTING,
3623 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3624 Py_END_ALLOW_THREADS
3625 if (hFile == INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003626 return win32_error_object("utime", obwpath);
3627 }
3628 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 /* Drop the argument parsing error as narrow strings
3630 are also valid. */
3631 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003632
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003633 if (!PyArg_ParseTuple(args, "y|O:utime", &apath, &arg))
3634 return NULL;
3635 if (win32_warn_bytes_api())
Victor Stinner8c62be82010-05-06 00:08:46 +00003636 return NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003637
Victor Stinner8c62be82010-05-06 00:08:46 +00003638 Py_BEGIN_ALLOW_THREADS
3639 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3640 NULL, OPEN_EXISTING,
3641 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3642 Py_END_ALLOW_THREADS
3643 if (hFile == INVALID_HANDLE_VALUE) {
3644 win32_error("utime", apath);
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 return NULL;
3646 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 }
3648
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003649 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003650 SYSTEMTIME now;
3651 GetSystemTime(&now);
3652 if (!SystemTimeToFileTime(&now, &mtime) ||
3653 !SystemTimeToFileTime(&now, &atime)) {
3654 win32_error("utime", NULL);
3655 goto done;
Stefan Krah0e803b32010-11-26 16:16:47 +00003656 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003657 }
3658 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3659 PyErr_SetString(PyExc_TypeError,
3660 "utime() arg 2 must be a tuple (atime, mtime)");
3661 goto done;
3662 }
3663 else {
3664 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003665 &atimesec, &ansec) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 goto done;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003667 time_t_to_FILE_TIME(atimesec, ansec, &atime);
Victor Stinner8c62be82010-05-06 00:08:46 +00003668 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003669 &mtimesec, &mnsec) == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 goto done;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003671 time_t_to_FILE_TIME(mtimesec, mnsec, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 }
3673 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3674 /* Avoid putting the file name into the error here,
3675 as that may confuse the user into believing that
3676 something is wrong with the file, when it also
3677 could be the time stamp that gives a problem. */
3678 win32_error("utime", NULL);
Antoine Pitroue85da7a2011-01-06 18:25:55 +00003679 goto done;
Victor Stinner8c62be82010-05-06 00:08:46 +00003680 }
3681 Py_INCREF(Py_None);
3682 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003683done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 CloseHandle(hFile);
3685 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003686#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003687
Victor Stinner8c62be82010-05-06 00:08:46 +00003688 PyObject *opath;
3689 char *path;
Amaury Forgeot d'Arca251a852011-01-03 00:19:11 +00003690 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003691 long ansec, mnsec;
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 int res;
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003693 PyObject* arg = Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003694
Brian Curtin52fbea12011-11-06 13:41:17 -06003695 if (!PyArg_ParseTuple(args, "O&|O:utime",
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 PyUnicode_FSConverter, &opath, &arg))
3697 return NULL;
3698 path = PyBytes_AsString(opath);
Brian Curtinb0d5b5d2011-11-07 10:51:18 -06003699 if (arg == Py_None) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 /* optional time values not given */
3701 Py_BEGIN_ALLOW_THREADS
3702 res = utime(path, NULL);
3703 Py_END_ALLOW_THREADS
3704 }
3705 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3706 PyErr_SetString(PyExc_TypeError,
3707 "utime() arg 2 must be a tuple (atime, mtime)");
3708 Py_DECREF(opath);
3709 return NULL;
3710 }
3711 else {
3712 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003713 &atime, &ansec) == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 Py_DECREF(opath);
3715 return NULL;
3716 }
3717 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003718 &mtime, &mnsec) == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003719 Py_DECREF(opath);
3720 return NULL;
3721 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003722
3723 Py_BEGIN_ALLOW_THREADS
3724 {
3725#ifdef HAVE_UTIMENSAT
3726 struct timespec buf[2];
3727 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003728 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003729 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003730 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003731 res = utimensat(AT_FDCWD, path, buf, 0);
3732#elif defined(HAVE_UTIMES)
3733 struct timeval buf[2];
3734 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003735 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003736 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003737 buf[1].tv_usec = mnsec / 1000;
Victor Stinner8c62be82010-05-06 00:08:46 +00003738 res = utimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003739#elif defined(HAVE_UTIME_H)
3740 /* XXX should define struct utimbuf instead, above */
3741 struct utimbuf buf;
3742 buf.actime = atime;
3743 buf.modtime = mtime;
3744 res = utime(path, &buf);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003745#else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003746 time_t buf[2];
3747 buf[0] = atime;
3748 buf[1] = mtime;
3749 res = utime(path, buf);
3750#endif
3751 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 }
3754 if (res < 0) {
3755 return posix_error_with_allocated_filename(opath);
3756 }
3757 Py_DECREF(opath);
3758 Py_INCREF(Py_None);
3759 return Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003760#undef UTIME_EXTRACT
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003761#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003762}
3763
Ross Lagerwall7807c352011-03-17 20:20:30 +02003764#ifdef HAVE_FUTIMES
3765PyDoc_STRVAR(posix_futimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003766"futimes(fd[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003767Set the access and modified time of the file specified by the file\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003768descriptor fd to the given values. If no second argument is used, set the\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003769access and modified times to the current time.");
3770
3771static PyObject *
3772posix_futimes(PyObject *self, PyObject *args)
3773{
3774 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003775 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003776 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003777 long ansec, mnsec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003778
Brian Curtinc1b65d12011-11-07 14:18:54 -06003779 if (!PyArg_ParseTuple(args, "i|O:futimes", &fd, &arg))
Ross Lagerwall7807c352011-03-17 20:20:30 +02003780 return NULL;
3781
3782 if (arg == Py_None) {
3783 /* optional time values not given */
3784 Py_BEGIN_ALLOW_THREADS
3785 res = futimes(fd, NULL);
3786 Py_END_ALLOW_THREADS
3787 }
3788 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3789 PyErr_SetString(PyExc_TypeError,
3790 "futimes() arg 2 must be a tuple (atime, mtime)");
3791 return NULL;
3792 }
3793 else {
3794 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003795 &atime, &ansec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003796 return NULL;
3797 }
3798 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003799 &mtime, &mnsec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003800 return NULL;
3801 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003802 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003803 {
3804#ifdef HAVE_FUTIMENS
3805 struct timespec buf[2];
3806 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003807 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003808 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003809 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003810 res = futimens(fd, buf);
3811#else
3812 struct timeval buf[2];
3813 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003814 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003815 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003816 buf[1].tv_usec = mnsec / 1000;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003817 res = futimes(fd, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003818#endif
3819 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003820 Py_END_ALLOW_THREADS
3821 }
3822 if (res < 0)
3823 return posix_error();
3824 Py_RETURN_NONE;
3825}
3826#endif
3827
3828#ifdef HAVE_LUTIMES
3829PyDoc_STRVAR(posix_lutimes__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003830"lutimes(path[, (atime, mtime)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003831Like utime(), but if path is a symbolic link, it is not dereferenced.");
3832
3833static PyObject *
3834posix_lutimes(PyObject *self, PyObject *args)
3835{
Brian Curtinc1b65d12011-11-07 14:18:54 -06003836 PyObject *opath;
3837 PyObject *arg = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003838 const char *path;
3839 int res;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003840 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003841 long ansec, mnsec;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003842
Brian Curtinc1b65d12011-11-07 14:18:54 -06003843 if (!PyArg_ParseTuple(args, "O&|O:lutimes",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003844 PyUnicode_FSConverter, &opath, &arg))
3845 return NULL;
3846 path = PyBytes_AsString(opath);
3847 if (arg == Py_None) {
3848 /* optional time values not given */
3849 Py_BEGIN_ALLOW_THREADS
3850 res = lutimes(path, NULL);
3851 Py_END_ALLOW_THREADS
3852 }
3853 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3854 PyErr_SetString(PyExc_TypeError,
3855 "lutimes() arg 2 must be a tuple (atime, mtime)");
3856 Py_DECREF(opath);
3857 return NULL;
3858 }
3859 else {
3860 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003861 &atime, &ansec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003862 Py_DECREF(opath);
3863 return NULL;
3864 }
3865 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01003866 &mtime, &mnsec) == -1) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02003867 Py_DECREF(opath);
3868 return NULL;
3869 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003870 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003871 {
3872#ifdef HAVE_UTIMENSAT
3873 struct timespec buf[2];
3874 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003875 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003876 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003877 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003878 res = utimensat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
3879#else
3880 struct timeval buf[2];
3881 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003882 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003883 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01003884 buf[1].tv_usec = mnsec / 1000;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003885 res = lutimes(path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07003886#endif
3887 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02003888 Py_END_ALLOW_THREADS
3889 }
3890 Py_DECREF(opath);
3891 if (res < 0)
3892 return posix_error();
3893 Py_RETURN_NONE;
3894}
3895#endif
3896
3897#ifdef HAVE_FUTIMENS
3898PyDoc_STRVAR(posix_futimens__doc__,
Brian Curtinc1b65d12011-11-07 14:18:54 -06003899"futimens(fd[, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec)])\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003900Updates the timestamps of a file specified by the file descriptor fd, with\n\
3901nanosecond precision.\n\
Brian Curtinc1b65d12011-11-07 14:18:54 -06003902If no second argument is given, set atime and mtime to the current time.\n\
Ross Lagerwall7807c352011-03-17 20:20:30 +02003903If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
3904current time.\n\
3905If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
3906
3907static PyObject *
3908posix_futimens(PyObject *self, PyObject *args)
3909{
3910 int res, fd;
Brian Curtinc1b65d12011-11-07 14:18:54 -06003911 PyObject *atime = Py_None;
3912 PyObject *mtime = Py_None;
Ross Lagerwall7807c352011-03-17 20:20:30 +02003913 struct timespec buf[2];
3914
Brian Curtinc1b65d12011-11-07 14:18:54 -06003915 if (!PyArg_ParseTuple(args, "i|OO:futimens",
Ross Lagerwall7807c352011-03-17 20:20:30 +02003916 &fd, &atime, &mtime))
3917 return NULL;
3918 if (atime == Py_None && mtime == Py_None) {
3919 /* optional time values not given */
3920 Py_BEGIN_ALLOW_THREADS
3921 res = futimens(fd, NULL);
3922 Py_END_ALLOW_THREADS
3923 }
3924 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
3925 PyErr_SetString(PyExc_TypeError,
3926 "futimens() arg 2 must be a tuple (atime_sec, atime_nsec)");
3927 return NULL;
3928 }
3929 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
3930 PyErr_SetString(PyExc_TypeError,
3931 "futimens() arg 3 must be a tuple (mtime_sec, mtime_nsec)");
3932 return NULL;
3933 }
3934 else {
3935 if (!PyArg_ParseTuple(atime, "ll:futimens",
3936 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
3937 return NULL;
3938 }
3939 if (!PyArg_ParseTuple(mtime, "ll:futimens",
3940 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
3941 return NULL;
3942 }
3943 Py_BEGIN_ALLOW_THREADS
3944 res = futimens(fd, buf);
3945 Py_END_ALLOW_THREADS
3946 }
3947 if (res < 0)
3948 return posix_error();
3949 Py_RETURN_NONE;
3950}
3951#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003952
Guido van Rossum3b066191991-06-04 19:40:25 +00003953/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003954
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003955PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003956"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003957Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003958
Barry Warsaw53699e91996-12-10 23:23:01 +00003959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003960posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003961{
Victor Stinner8c62be82010-05-06 00:08:46 +00003962 int sts;
3963 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3964 return NULL;
3965 _exit(sts);
3966 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003967}
3968
Martin v. Löwis114619e2002-10-07 06:44:21 +00003969#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3970static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003971free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003972{
Victor Stinner8c62be82010-05-06 00:08:46 +00003973 Py_ssize_t i;
3974 for (i = 0; i < count; i++)
3975 PyMem_Free(array[i]);
3976 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003977}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003978
Antoine Pitrou69f71142009-05-24 21:25:49 +00003979static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003980int fsconvert_strdup(PyObject *o, char**out)
3981{
Victor Stinner8c62be82010-05-06 00:08:46 +00003982 PyObject *bytes;
3983 Py_ssize_t size;
3984 if (!PyUnicode_FSConverter(o, &bytes))
3985 return 0;
3986 size = PyBytes_GET_SIZE(bytes);
3987 *out = PyMem_Malloc(size+1);
3988 if (!*out)
3989 return 0;
3990 memcpy(*out, PyBytes_AsString(bytes), size+1);
3991 Py_DECREF(bytes);
3992 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003993}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003994#endif
3995
Ross Lagerwall7807c352011-03-17 20:20:30 +02003996#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00003997static char**
3998parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3999{
Victor Stinner8c62be82010-05-06 00:08:46 +00004000 char **envlist;
4001 Py_ssize_t i, pos, envc;
4002 PyObject *keys=NULL, *vals=NULL;
4003 PyObject *key, *val, *key2, *val2;
4004 char *p, *k, *v;
4005 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004006
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 i = PyMapping_Size(env);
4008 if (i < 0)
4009 return NULL;
4010 envlist = PyMem_NEW(char *, i + 1);
4011 if (envlist == NULL) {
4012 PyErr_NoMemory();
4013 return NULL;
4014 }
4015 envc = 0;
4016 keys = PyMapping_Keys(env);
4017 vals = PyMapping_Values(env);
4018 if (!keys || !vals)
4019 goto error;
4020 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4021 PyErr_Format(PyExc_TypeError,
4022 "env.keys() or env.values() is not a list");
4023 goto error;
4024 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004025
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 for (pos = 0; pos < i; pos++) {
4027 key = PyList_GetItem(keys, pos);
4028 val = PyList_GetItem(vals, pos);
4029 if (!key || !val)
4030 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004031
Victor Stinner8c62be82010-05-06 00:08:46 +00004032 if (PyUnicode_FSConverter(key, &key2) == 0)
4033 goto error;
4034 if (PyUnicode_FSConverter(val, &val2) == 0) {
4035 Py_DECREF(key2);
4036 goto error;
4037 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004038
4039#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004040 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
4041 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00004042#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004043 k = PyBytes_AsString(key2);
4044 v = PyBytes_AsString(val2);
4045 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004046
Victor Stinner8c62be82010-05-06 00:08:46 +00004047 p = PyMem_NEW(char, len);
4048 if (p == NULL) {
4049 PyErr_NoMemory();
4050 Py_DECREF(key2);
4051 Py_DECREF(val2);
4052 goto error;
4053 }
4054 PyOS_snprintf(p, len, "%s=%s", k, v);
4055 envlist[envc++] = p;
4056 Py_DECREF(key2);
4057 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004058#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00004059 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004060#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 }
4062 Py_DECREF(vals);
4063 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004064
Victor Stinner8c62be82010-05-06 00:08:46 +00004065 envlist[envc] = 0;
4066 *envc_ptr = envc;
4067 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004068
4069error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004070 Py_XDECREF(keys);
4071 Py_XDECREF(vals);
4072 while (--envc >= 0)
4073 PyMem_DEL(envlist[envc]);
4074 PyMem_DEL(envlist);
4075 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004076}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004077
Ross Lagerwall7807c352011-03-17 20:20:30 +02004078static char**
4079parse_arglist(PyObject* argv, Py_ssize_t *argc)
4080{
4081 int i;
4082 char **argvlist = PyMem_NEW(char *, *argc+1);
4083 if (argvlist == NULL) {
4084 PyErr_NoMemory();
4085 return NULL;
4086 }
4087 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004088 PyObject* item = PySequence_ITEM(argv, i);
4089 if (item == NULL)
4090 goto fail;
4091 if (!fsconvert_strdup(item, &argvlist[i])) {
4092 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004093 goto fail;
4094 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004095 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004096 }
4097 argvlist[*argc] = NULL;
4098 return argvlist;
4099fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004100 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004101 free_string_array(argvlist, *argc);
4102 return NULL;
4103}
4104#endif
4105
4106#ifdef HAVE_EXECV
4107PyDoc_STRVAR(posix_execv__doc__,
4108"execv(path, args)\n\n\
4109Execute an executable path with arguments, replacing current process.\n\
4110\n\
4111 path: path of executable file\n\
4112 args: tuple or list of strings");
4113
4114static PyObject *
4115posix_execv(PyObject *self, PyObject *args)
4116{
4117 PyObject *opath;
4118 char *path;
4119 PyObject *argv;
4120 char **argvlist;
4121 Py_ssize_t argc;
4122
4123 /* execv has two arguments: (path, argv), where
4124 argv is a list or tuple of strings. */
4125
4126 if (!PyArg_ParseTuple(args, "O&O:execv",
4127 PyUnicode_FSConverter,
4128 &opath, &argv))
4129 return NULL;
4130 path = PyBytes_AsString(opath);
4131 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4132 PyErr_SetString(PyExc_TypeError,
4133 "execv() arg 2 must be a tuple or list");
4134 Py_DECREF(opath);
4135 return NULL;
4136 }
4137 argc = PySequence_Size(argv);
4138 if (argc < 1) {
4139 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
4140 Py_DECREF(opath);
4141 return NULL;
4142 }
4143
4144 argvlist = parse_arglist(argv, &argc);
4145 if (argvlist == NULL) {
4146 Py_DECREF(opath);
4147 return NULL;
4148 }
4149
4150 execv(path, argvlist);
4151
4152 /* If we get here it's definitely an error */
4153
4154 free_string_array(argvlist, argc);
4155 Py_DECREF(opath);
4156 return posix_error();
4157}
4158
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004159PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004160"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004161Execute a path with arguments and environment, replacing current process.\n\
4162\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004163 path: path of executable file\n\
4164 args: tuple or list of arguments\n\
4165 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004166
Barry Warsaw53699e91996-12-10 23:23:01 +00004167static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004168posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004169{
Victor Stinner8c62be82010-05-06 00:08:46 +00004170 PyObject *opath;
4171 char *path;
4172 PyObject *argv, *env;
4173 char **argvlist;
4174 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004175 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004176
Victor Stinner8c62be82010-05-06 00:08:46 +00004177 /* execve has three arguments: (path, argv, env), where
4178 argv is a list or tuple of strings and env is a dictionary
4179 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004180
Victor Stinner8c62be82010-05-06 00:08:46 +00004181 if (!PyArg_ParseTuple(args, "O&OO:execve",
4182 PyUnicode_FSConverter,
4183 &opath, &argv, &env))
4184 return NULL;
4185 path = PyBytes_AsString(opath);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004186 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004187 PyErr_SetString(PyExc_TypeError,
4188 "execve() arg 2 must be a tuple or list");
4189 goto fail_0;
4190 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004191 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 if (!PyMapping_Check(env)) {
4193 PyErr_SetString(PyExc_TypeError,
4194 "execve() arg 3 must be a mapping object");
4195 goto fail_0;
4196 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004197
Ross Lagerwall7807c352011-03-17 20:20:30 +02004198 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004200 goto fail_0;
4201 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004202
Victor Stinner8c62be82010-05-06 00:08:46 +00004203 envlist = parse_envlist(env, &envc);
4204 if (envlist == NULL)
4205 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004206
Victor Stinner8c62be82010-05-06 00:08:46 +00004207 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00004208
Victor Stinner8c62be82010-05-06 00:08:46 +00004209 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004210
Victor Stinner8c62be82010-05-06 00:08:46 +00004211 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004212
Victor Stinner8c62be82010-05-06 00:08:46 +00004213 while (--envc >= 0)
4214 PyMem_DEL(envlist[envc]);
4215 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004216 fail_1:
Ross Lagerwall7807c352011-03-17 20:20:30 +02004217 free_string_array(argvlist, argc);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004218 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004219 Py_DECREF(opath);
4220 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004221}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004222#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004223
Ross Lagerwall7807c352011-03-17 20:20:30 +02004224#ifdef HAVE_FEXECVE
4225PyDoc_STRVAR(posix_fexecve__doc__,
4226"fexecve(fd, args, env)\n\n\
4227Execute the program specified by a file descriptor with arguments and\n\
4228environment, replacing the current process.\n\
4229\n\
4230 fd: file descriptor of executable\n\
4231 args: tuple or list of arguments\n\
4232 env: dictionary of strings mapping to strings");
4233
4234static PyObject *
4235posix_fexecve(PyObject *self, PyObject *args)
4236{
4237 int fd;
4238 PyObject *argv, *env;
4239 char **argvlist;
4240 char **envlist;
4241 Py_ssize_t argc, envc;
4242
4243 if (!PyArg_ParseTuple(args, "iOO:fexecve",
4244 &fd, &argv, &env))
4245 return NULL;
4246 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4247 PyErr_SetString(PyExc_TypeError,
4248 "fexecve() arg 2 must be a tuple or list");
4249 return NULL;
4250 }
4251 argc = PySequence_Size(argv);
4252 if (!PyMapping_Check(env)) {
4253 PyErr_SetString(PyExc_TypeError,
4254 "fexecve() arg 3 must be a mapping object");
4255 return NULL;
4256 }
4257
4258 argvlist = parse_arglist(argv, &argc);
4259 if (argvlist == NULL)
4260 return NULL;
4261
4262 envlist = parse_envlist(env, &envc);
4263 if (envlist == NULL)
4264 goto fail;
4265
4266 fexecve(fd, argvlist, envlist);
4267
4268 /* If we get here it's definitely an error */
4269
4270 (void) posix_error();
4271
4272 while (--envc >= 0)
4273 PyMem_DEL(envlist[envc]);
4274 PyMem_DEL(envlist);
4275 fail:
4276 free_string_array(argvlist, argc);
4277 return NULL;
4278}
4279#endif /* HAVE_FEXECVE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004280
Guido van Rossuma1065681999-01-25 23:20:23 +00004281#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004282PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004283"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004284Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004285\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004286 mode: mode of process creation\n\
4287 path: path of executable file\n\
4288 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004289
4290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004291posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004292{
Victor Stinner8c62be82010-05-06 00:08:46 +00004293 PyObject *opath;
4294 char *path;
4295 PyObject *argv;
4296 char **argvlist;
4297 int mode, i;
4298 Py_ssize_t argc;
4299 Py_intptr_t spawnval;
4300 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004301
Victor Stinner8c62be82010-05-06 00:08:46 +00004302 /* spawnv has three arguments: (mode, path, argv), where
4303 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004304
Victor Stinner8c62be82010-05-06 00:08:46 +00004305 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
4306 PyUnicode_FSConverter,
4307 &opath, &argv))
4308 return NULL;
4309 path = PyBytes_AsString(opath);
4310 if (PyList_Check(argv)) {
4311 argc = PyList_Size(argv);
4312 getitem = PyList_GetItem;
4313 }
4314 else if (PyTuple_Check(argv)) {
4315 argc = PyTuple_Size(argv);
4316 getitem = PyTuple_GetItem;
4317 }
4318 else {
4319 PyErr_SetString(PyExc_TypeError,
4320 "spawnv() arg 2 must be a tuple or list");
4321 Py_DECREF(opath);
4322 return NULL;
4323 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004324
Victor Stinner8c62be82010-05-06 00:08:46 +00004325 argvlist = PyMem_NEW(char *, argc+1);
4326 if (argvlist == NULL) {
4327 Py_DECREF(opath);
4328 return PyErr_NoMemory();
4329 }
4330 for (i = 0; i < argc; i++) {
4331 if (!fsconvert_strdup((*getitem)(argv, i),
4332 &argvlist[i])) {
4333 free_string_array(argvlist, i);
4334 PyErr_SetString(
4335 PyExc_TypeError,
4336 "spawnv() arg 2 must contain only strings");
4337 Py_DECREF(opath);
4338 return NULL;
4339 }
4340 }
4341 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004342
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004343#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004344 Py_BEGIN_ALLOW_THREADS
4345 spawnval = spawnv(mode, path, argvlist);
4346 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004347#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004348 if (mode == _OLD_P_OVERLAY)
4349 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00004350
Victor Stinner8c62be82010-05-06 00:08:46 +00004351 Py_BEGIN_ALLOW_THREADS
4352 spawnval = _spawnv(mode, path, argvlist);
4353 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004354#endif
Tim Peters5aa91602002-01-30 05:46:57 +00004355
Victor Stinner8c62be82010-05-06 00:08:46 +00004356 free_string_array(argvlist, argc);
4357 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00004358
Victor Stinner8c62be82010-05-06 00:08:46 +00004359 if (spawnval == -1)
4360 return posix_error();
4361 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004362#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004363 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004364#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004365 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004366#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004367}
4368
4369
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004370PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004371"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00004372Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00004373\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004374 mode: mode of process creation\n\
4375 path: path of executable file\n\
4376 args: tuple or list of arguments\n\
4377 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00004378
4379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004380posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00004381{
Victor Stinner8c62be82010-05-06 00:08:46 +00004382 PyObject *opath;
4383 char *path;
4384 PyObject *argv, *env;
4385 char **argvlist;
4386 char **envlist;
4387 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004388 int mode;
4389 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004390 Py_intptr_t spawnval;
4391 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4392 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00004393
Victor Stinner8c62be82010-05-06 00:08:46 +00004394 /* spawnve has four arguments: (mode, path, argv, env), where
4395 argv is a list or tuple of strings and env is a dictionary
4396 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004397
Victor Stinner8c62be82010-05-06 00:08:46 +00004398 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
4399 PyUnicode_FSConverter,
4400 &opath, &argv, &env))
4401 return NULL;
4402 path = PyBytes_AsString(opath);
4403 if (PyList_Check(argv)) {
4404 argc = PyList_Size(argv);
4405 getitem = PyList_GetItem;
4406 }
4407 else if (PyTuple_Check(argv)) {
4408 argc = PyTuple_Size(argv);
4409 getitem = PyTuple_GetItem;
4410 }
4411 else {
4412 PyErr_SetString(PyExc_TypeError,
4413 "spawnve() arg 2 must be a tuple or list");
4414 goto fail_0;
4415 }
4416 if (!PyMapping_Check(env)) {
4417 PyErr_SetString(PyExc_TypeError,
4418 "spawnve() arg 3 must be a mapping object");
4419 goto fail_0;
4420 }
Guido van Rossuma1065681999-01-25 23:20:23 +00004421
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 argvlist = PyMem_NEW(char *, argc+1);
4423 if (argvlist == NULL) {
4424 PyErr_NoMemory();
4425 goto fail_0;
4426 }
4427 for (i = 0; i < argc; i++) {
4428 if (!fsconvert_strdup((*getitem)(argv, i),
4429 &argvlist[i]))
4430 {
4431 lastarg = i;
4432 goto fail_1;
4433 }
4434 }
4435 lastarg = argc;
4436 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00004437
Victor Stinner8c62be82010-05-06 00:08:46 +00004438 envlist = parse_envlist(env, &envc);
4439 if (envlist == NULL)
4440 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00004441
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004442#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004443 Py_BEGIN_ALLOW_THREADS
4444 spawnval = spawnve(mode, path, argvlist, envlist);
4445 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004446#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004447 if (mode == _OLD_P_OVERLAY)
4448 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00004449
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 Py_BEGIN_ALLOW_THREADS
4451 spawnval = _spawnve(mode, path, argvlist, envlist);
4452 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004453#endif
Tim Peters25059d32001-12-07 20:35:43 +00004454
Victor Stinner8c62be82010-05-06 00:08:46 +00004455 if (spawnval == -1)
4456 (void) posix_error();
4457 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00004458#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00004459 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004460#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004461 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00004462#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00004463
Victor Stinner8c62be82010-05-06 00:08:46 +00004464 while (--envc >= 0)
4465 PyMem_DEL(envlist[envc]);
4466 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00004467 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004468 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004469 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004470 Py_DECREF(opath);
4471 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00004472}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004473
4474/* OS/2 supports spawnvp & spawnvpe natively */
4475#if defined(PYOS_OS2)
4476PyDoc_STRVAR(posix_spawnvp__doc__,
4477"spawnvp(mode, file, args)\n\n\
4478Execute the program 'file' in a new process, using the environment\n\
4479search path to find the file.\n\
4480\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004481 mode: mode of process creation\n\
4482 file: executable file name\n\
4483 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004484
4485static PyObject *
4486posix_spawnvp(PyObject *self, PyObject *args)
4487{
Victor Stinner8c62be82010-05-06 00:08:46 +00004488 PyObject *opath;
4489 char *path;
4490 PyObject *argv;
4491 char **argvlist;
4492 int mode, i, argc;
4493 Py_intptr_t spawnval;
4494 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004495
Victor Stinner8c62be82010-05-06 00:08:46 +00004496 /* spawnvp has three arguments: (mode, path, argv), where
4497 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004498
Victor Stinner8c62be82010-05-06 00:08:46 +00004499 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
4500 PyUnicode_FSConverter,
4501 &opath, &argv))
4502 return NULL;
4503 path = PyBytes_AsString(opath);
4504 if (PyList_Check(argv)) {
4505 argc = PyList_Size(argv);
4506 getitem = PyList_GetItem;
4507 }
4508 else if (PyTuple_Check(argv)) {
4509 argc = PyTuple_Size(argv);
4510 getitem = PyTuple_GetItem;
4511 }
4512 else {
4513 PyErr_SetString(PyExc_TypeError,
4514 "spawnvp() arg 2 must be a tuple or list");
4515 Py_DECREF(opath);
4516 return NULL;
4517 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004518
Victor Stinner8c62be82010-05-06 00:08:46 +00004519 argvlist = PyMem_NEW(char *, argc+1);
4520 if (argvlist == NULL) {
4521 Py_DECREF(opath);
4522 return PyErr_NoMemory();
4523 }
4524 for (i = 0; i < argc; i++) {
4525 if (!fsconvert_strdup((*getitem)(argv, i),
4526 &argvlist[i])) {
4527 free_string_array(argvlist, i);
4528 PyErr_SetString(
4529 PyExc_TypeError,
4530 "spawnvp() arg 2 must contain only strings");
4531 Py_DECREF(opath);
4532 return NULL;
4533 }
4534 }
4535 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004536
Victor Stinner8c62be82010-05-06 00:08:46 +00004537 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004538#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004539 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004540#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004541 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004542#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004543 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004544
Victor Stinner8c62be82010-05-06 00:08:46 +00004545 free_string_array(argvlist, argc);
4546 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004547
Victor Stinner8c62be82010-05-06 00:08:46 +00004548 if (spawnval == -1)
4549 return posix_error();
4550 else
4551 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004552}
4553
4554
4555PyDoc_STRVAR(posix_spawnvpe__doc__,
4556"spawnvpe(mode, file, args, env)\n\n\
4557Execute the program 'file' in a new process, using the environment\n\
4558search path to find the file.\n\
4559\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00004560 mode: mode of process creation\n\
4561 file: executable file name\n\
4562 args: tuple or list of arguments\n\
4563 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004564
4565static PyObject *
4566posix_spawnvpe(PyObject *self, PyObject *args)
4567{
Ross Lagerwalldcfde5a2011-11-04 07:09:14 +02004568 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00004569 char *path;
4570 PyObject *argv, *env;
4571 char **argvlist;
4572 char **envlist;
4573 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00004574 int mode;
4575 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00004576 Py_intptr_t spawnval;
4577 PyObject *(*getitem)(PyObject *, Py_ssize_t);
4578 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004579
Victor Stinner8c62be82010-05-06 00:08:46 +00004580 /* spawnvpe has four arguments: (mode, path, argv, env), where
4581 argv is a list or tuple of strings and env is a dictionary
4582 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004583
Victor Stinner8c62be82010-05-06 00:08:46 +00004584 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
4585 PyUnicode_FSConverter,
4586 &opath, &argv, &env))
4587 return NULL;
4588 path = PyBytes_AsString(opath);
4589 if (PyList_Check(argv)) {
4590 argc = PyList_Size(argv);
4591 getitem = PyList_GetItem;
4592 }
4593 else if (PyTuple_Check(argv)) {
4594 argc = PyTuple_Size(argv);
4595 getitem = PyTuple_GetItem;
4596 }
4597 else {
4598 PyErr_SetString(PyExc_TypeError,
4599 "spawnvpe() arg 2 must be a tuple or list");
4600 goto fail_0;
4601 }
4602 if (!PyMapping_Check(env)) {
4603 PyErr_SetString(PyExc_TypeError,
4604 "spawnvpe() arg 3 must be a mapping object");
4605 goto fail_0;
4606 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004607
Victor Stinner8c62be82010-05-06 00:08:46 +00004608 argvlist = PyMem_NEW(char *, argc+1);
4609 if (argvlist == NULL) {
4610 PyErr_NoMemory();
4611 goto fail_0;
4612 }
4613 for (i = 0; i < argc; i++) {
4614 if (!fsconvert_strdup((*getitem)(argv, i),
4615 &argvlist[i]))
4616 {
4617 lastarg = i;
4618 goto fail_1;
4619 }
4620 }
4621 lastarg = argc;
4622 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004623
Victor Stinner8c62be82010-05-06 00:08:46 +00004624 envlist = parse_envlist(env, &envc);
4625 if (envlist == NULL)
4626 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004627
Victor Stinner8c62be82010-05-06 00:08:46 +00004628 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004629#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004630 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004631#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004632 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004633#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004634 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004635
Victor Stinner8c62be82010-05-06 00:08:46 +00004636 if (spawnval == -1)
4637 (void) posix_error();
4638 else
4639 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004640
Victor Stinner8c62be82010-05-06 00:08:46 +00004641 while (--envc >= 0)
4642 PyMem_DEL(envlist[envc]);
4643 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004644 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00004645 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004646 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00004647 Py_DECREF(opath);
4648 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00004649}
4650#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00004651#endif /* HAVE_SPAWNV */
4652
4653
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004654#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004655PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004656"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004657Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
4658\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004659Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004660
4661static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004662posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004663{
Victor Stinner8c62be82010-05-06 00:08:46 +00004664 pid_t pid;
4665 int result = 0;
4666 _PyImport_AcquireLock();
4667 pid = fork1();
4668 if (pid == 0) {
4669 /* child: this clobbers and resets the import lock. */
4670 PyOS_AfterFork();
4671 } else {
4672 /* parent: release the import lock. */
4673 result = _PyImport_ReleaseLock();
4674 }
4675 if (pid == -1)
4676 return posix_error();
4677 if (result < 0) {
4678 /* Don't clobber the OSError if the fork failed. */
4679 PyErr_SetString(PyExc_RuntimeError,
4680 "not holding the import lock");
4681 return NULL;
4682 }
4683 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00004684}
4685#endif
4686
4687
Guido van Rossumad0ee831995-03-01 10:34:45 +00004688#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004689PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004690"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004691Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004692Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004693
Barry Warsaw53699e91996-12-10 23:23:01 +00004694static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004695posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004696{
Victor Stinner8c62be82010-05-06 00:08:46 +00004697 pid_t pid;
4698 int result = 0;
4699 _PyImport_AcquireLock();
4700 pid = fork();
4701 if (pid == 0) {
4702 /* child: this clobbers and resets the import lock. */
4703 PyOS_AfterFork();
4704 } else {
4705 /* parent: release the import lock. */
4706 result = _PyImport_ReleaseLock();
4707 }
4708 if (pid == -1)
4709 return posix_error();
4710 if (result < 0) {
4711 /* Don't clobber the OSError if the fork failed. */
4712 PyErr_SetString(PyExc_RuntimeError,
4713 "not holding the import lock");
4714 return NULL;
4715 }
4716 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004717}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004718#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004719
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004720#ifdef HAVE_SCHED_H
4721
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004722#ifdef HAVE_SCHED_GET_PRIORITY_MAX
4723
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004724PyDoc_STRVAR(posix_sched_get_priority_max__doc__,
4725"sched_get_priority_max(policy)\n\n\
4726Get the maximum scheduling priority for *policy*.");
4727
4728static PyObject *
4729posix_sched_get_priority_max(PyObject *self, PyObject *args)
4730{
4731 int policy, max;
4732
4733 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy))
4734 return NULL;
4735 max = sched_get_priority_max(policy);
4736 if (max < 0)
4737 return posix_error();
4738 return PyLong_FromLong(max);
4739}
4740
4741PyDoc_STRVAR(posix_sched_get_priority_min__doc__,
4742"sched_get_priority_min(policy)\n\n\
4743Get the minimum scheduling priority for *policy*.");
4744
4745static PyObject *
4746posix_sched_get_priority_min(PyObject *self, PyObject *args)
4747{
4748 int policy, min;
4749
4750 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy))
4751 return NULL;
4752 min = sched_get_priority_min(policy);
4753 if (min < 0)
4754 return posix_error();
4755 return PyLong_FromLong(min);
4756}
4757
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02004758#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
4759
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004760#ifdef HAVE_SCHED_SETSCHEDULER
4761
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004762PyDoc_STRVAR(posix_sched_getscheduler__doc__,
4763"sched_getscheduler(pid)\n\n\
4764Get the scheduling policy for the process with a PID of *pid*.\n\
4765Passing a PID of 0 returns the scheduling policy for the calling process.");
4766
4767static PyObject *
4768posix_sched_getscheduler(PyObject *self, PyObject *args)
4769{
4770 pid_t pid;
4771 int policy;
4772
4773 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid))
4774 return NULL;
4775 policy = sched_getscheduler(pid);
4776 if (policy < 0)
4777 return posix_error();
4778 return PyLong_FromLong(policy);
4779}
4780
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004781#endif
4782
4783#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
4784
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004785static PyObject *
4786sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4787{
4788 PyObject *res, *priority;
Benjamin Peterson4e36d5a2011-08-02 19:56:11 -05004789 static char *kwlist[] = {"sched_priority", NULL};
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004790
4791 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority))
4792 return NULL;
4793 res = PyStructSequence_New(type);
4794 if (!res)
4795 return NULL;
4796 Py_INCREF(priority);
4797 PyStructSequence_SET_ITEM(res, 0, priority);
4798 return res;
4799}
4800
4801PyDoc_STRVAR(sched_param__doc__,
4802"sched_param(sched_priority): A scheduling parameter.\n\n\
4803Current has only one field: sched_priority");
4804
4805static PyStructSequence_Field sched_param_fields[] = {
4806 {"sched_priority", "the scheduling priority"},
4807 {0}
4808};
4809
4810static PyStructSequence_Desc sched_param_desc = {
4811 "sched_param", /* name */
4812 sched_param__doc__, /* doc */
4813 sched_param_fields,
4814 1
4815};
4816
4817static int
4818convert_sched_param(PyObject *param, struct sched_param *res)
4819{
4820 long priority;
4821
4822 if (Py_TYPE(param) != &SchedParamType) {
4823 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
4824 return 0;
4825 }
4826 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
4827 if (priority == -1 && PyErr_Occurred())
4828 return 0;
4829 if (priority > INT_MAX || priority < INT_MIN) {
4830 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
4831 return 0;
4832 }
4833 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
4834 return 1;
4835}
4836
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004837#endif
4838
4839#ifdef HAVE_SCHED_SETSCHEDULER
4840
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004841PyDoc_STRVAR(posix_sched_setscheduler__doc__,
4842"sched_setscheduler(pid, policy, param)\n\n\
4843Set the scheduling policy, *policy*, for *pid*.\n\
4844If *pid* is 0, the calling process is changed.\n\
4845*param* is an instance of sched_param.");
4846
4847static PyObject *
4848posix_sched_setscheduler(PyObject *self, PyObject *args)
4849{
4850 pid_t pid;
4851 int policy;
4852 struct sched_param param;
4853
4854 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler",
4855 &pid, &policy, &convert_sched_param, &param))
4856 return NULL;
Jesus Cea9c822272011-09-10 01:40:52 +02004857
4858 /*
Jesus Cea54b01492011-09-10 01:53:19 +02004859 ** sched_setscheduler() returns 0 in Linux, but the previous
4860 ** scheduling policy under Solaris/Illumos, and others.
4861 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02004862 */
4863 if (sched_setscheduler(pid, policy, &param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004864 return posix_error();
4865 Py_RETURN_NONE;
4866}
4867
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004868#endif
4869
4870#ifdef HAVE_SCHED_SETPARAM
4871
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004872PyDoc_STRVAR(posix_sched_getparam__doc__,
4873"sched_getparam(pid) -> sched_param\n\n\
4874Returns scheduling parameters for the process with *pid* as an instance of the\n\
4875sched_param class. A PID of 0 means the calling process.");
4876
4877static PyObject *
4878posix_sched_getparam(PyObject *self, PyObject *args)
4879{
4880 pid_t pid;
4881 struct sched_param param;
4882 PyObject *res, *priority;
4883
4884 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid))
4885 return NULL;
4886 if (sched_getparam(pid, &param))
4887 return posix_error();
4888 res = PyStructSequence_New(&SchedParamType);
4889 if (!res)
4890 return NULL;
4891 priority = PyLong_FromLong(param.sched_priority);
4892 if (!priority) {
4893 Py_DECREF(res);
4894 return NULL;
4895 }
4896 PyStructSequence_SET_ITEM(res, 0, priority);
4897 return res;
4898}
4899
4900PyDoc_STRVAR(posix_sched_setparam__doc__,
4901"sched_setparam(pid, param)\n\n\
4902Set scheduling parameters for a process with PID *pid*.\n\
4903A PID of 0 means the calling process.");
4904
4905static PyObject *
4906posix_sched_setparam(PyObject *self, PyObject *args)
4907{
4908 pid_t pid;
4909 struct sched_param param;
4910
4911 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam",
4912 &pid, &convert_sched_param, &param))
4913 return NULL;
4914 if (sched_setparam(pid, &param))
4915 return posix_error();
4916 Py_RETURN_NONE;
4917}
4918
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004919#endif
4920
4921#ifdef HAVE_SCHED_RR_GET_INTERVAL
4922
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004923PyDoc_STRVAR(posix_sched_rr_get_interval__doc__,
4924"sched_rr_get_interval(pid) -> float\n\n\
4925Return the round-robin quantum for the process with PID *pid* in seconds.");
4926
4927static PyObject *
4928posix_sched_rr_get_interval(PyObject *self, PyObject *args)
4929{
4930 pid_t pid;
4931 struct timespec interval;
4932
4933 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid))
4934 return NULL;
4935 if (sched_rr_get_interval(pid, &interval))
4936 return posix_error();
4937 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec);
4938}
4939
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05004940#endif
4941
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004942PyDoc_STRVAR(posix_sched_yield__doc__,
4943"sched_yield()\n\n\
4944Voluntarily relinquish the CPU.");
4945
4946static PyObject *
4947posix_sched_yield(PyObject *self, PyObject *noargs)
4948{
4949 if (sched_yield())
4950 return posix_error();
4951 Py_RETURN_NONE;
4952}
4953
Benjamin Peterson2740af82011-08-02 17:41:34 -05004954#ifdef HAVE_SCHED_SETAFFINITY
4955
Benjamin Peterson94b580d2011-08-02 17:30:04 -05004956typedef struct {
4957 PyObject_HEAD;
4958 Py_ssize_t size;
4959 int ncpus;
4960 cpu_set_t *set;
4961} Py_cpu_set;
4962
4963static PyTypeObject cpu_set_type;
4964
4965static void
4966cpu_set_dealloc(Py_cpu_set *set)
4967{
4968 assert(set->set);
4969 CPU_FREE(set->set);
4970 Py_TYPE(set)->tp_free(set);
4971}
4972
4973static Py_cpu_set *
4974make_new_cpu_set(PyTypeObject *type, Py_ssize_t size)
4975{
4976 Py_cpu_set *set;
4977
4978 if (size < 0) {
4979 PyErr_SetString(PyExc_ValueError, "negative size");
4980 return NULL;
4981 }
4982 set = (Py_cpu_set *)type->tp_alloc(type, 0);
4983 if (!set)
4984 return NULL;
4985 set->ncpus = size;
4986 set->size = CPU_ALLOC_SIZE(size);
4987 set->set = CPU_ALLOC(size);
4988 if (!set->set) {
4989 type->tp_free(set);
4990 PyErr_NoMemory();
4991 return NULL;
4992 }
4993 CPU_ZERO_S(set->size, set->set);
4994 return set;
4995}
4996
4997static PyObject *
4998cpu_set_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4999{
5000 int size;
5001
5002 if (!_PyArg_NoKeywords("cpu_set()", kwargs) ||
5003 !PyArg_ParseTuple(args, "i:cpu_set", &size))
5004 return NULL;
5005 return (PyObject *)make_new_cpu_set(type, size);
5006}
5007
5008static PyObject *
5009cpu_set_repr(Py_cpu_set *set)
5010{
5011 return PyUnicode_FromFormat("<cpu_set with %li entries>", set->ncpus);
Victor Stinner63941882011-09-29 00:42:28 +02005012}
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005013
5014static Py_ssize_t
5015cpu_set_len(Py_cpu_set *set)
5016{
5017 return set->ncpus;
5018}
5019
5020static int
5021_get_cpu(Py_cpu_set *set, const char *requester, PyObject *args)
5022{
5023 int cpu;
5024 if (!PyArg_ParseTuple(args, requester, &cpu))
5025 return -1;
5026 if (cpu < 0) {
5027 PyErr_SetString(PyExc_ValueError, "cpu < 0 not valid");
5028 return -1;
5029 }
5030 if (cpu >= set->ncpus) {
5031 PyErr_SetString(PyExc_ValueError, "cpu too large for set");
5032 return -1;
5033 }
5034 return cpu;
5035}
5036
5037PyDoc_STRVAR(cpu_set_set_doc,
5038"cpu_set.set(i)\n\n\
5039Add CPU *i* to the set.");
5040
5041static PyObject *
5042cpu_set_set(Py_cpu_set *set, PyObject *args)
5043{
5044 int cpu = _get_cpu(set, "i|set", args);
5045 if (cpu == -1)
5046 return NULL;
5047 CPU_SET_S(cpu, set->size, set->set);
5048 Py_RETURN_NONE;
5049}
5050
5051PyDoc_STRVAR(cpu_set_count_doc,
5052"cpu_set.count() -> int\n\n\
5053Return the number of CPUs active in the set.");
5054
5055static PyObject *
5056cpu_set_count(Py_cpu_set *set, PyObject *noargs)
5057{
5058 return PyLong_FromLong(CPU_COUNT_S(set->size, set->set));
5059}
5060
5061PyDoc_STRVAR(cpu_set_clear_doc,
5062"cpu_set.clear(i)\n\n\
5063Remove CPU *i* from the set.");
5064
5065static PyObject *
5066cpu_set_clear(Py_cpu_set *set, PyObject *args)
5067{
5068 int cpu = _get_cpu(set, "i|clear", args);
5069 if (cpu == -1)
5070 return NULL;
5071 CPU_CLR_S(cpu, set->size, set->set);
5072 Py_RETURN_NONE;
5073}
5074
5075PyDoc_STRVAR(cpu_set_isset_doc,
5076"cpu_set.isset(i) -> bool\n\n\
5077Test if CPU *i* is in the set.");
5078
5079static PyObject *
5080cpu_set_isset(Py_cpu_set *set, PyObject *args)
5081{
5082 int cpu = _get_cpu(set, "i|isset", args);
5083 if (cpu == -1)
5084 return NULL;
5085 if (CPU_ISSET_S(cpu, set->size, set->set))
5086 Py_RETURN_TRUE;
5087 Py_RETURN_FALSE;
5088}
5089
5090PyDoc_STRVAR(cpu_set_zero_doc,
5091"cpu_set.zero()\n\n\
5092Clear the cpu_set.");
5093
5094static PyObject *
5095cpu_set_zero(Py_cpu_set *set, PyObject *noargs)
5096{
5097 CPU_ZERO_S(set->size, set->set);
5098 Py_RETURN_NONE;
5099}
5100
5101static PyObject *
5102cpu_set_richcompare(Py_cpu_set *set, Py_cpu_set *other, int op)
5103{
5104 int eq;
5105
Brian Curtindfc80e32011-08-10 20:28:54 -05005106 if ((op != Py_EQ && op != Py_NE) || Py_TYPE(other) != &cpu_set_type)
5107 Py_RETURN_NOTIMPLEMENTED;
5108
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005109 eq = set->ncpus == other->ncpus && CPU_EQUAL_S(set->size, set->set, other->set);
5110 if ((op == Py_EQ) ? eq : !eq)
5111 Py_RETURN_TRUE;
5112 else
5113 Py_RETURN_FALSE;
5114}
5115
5116#define CPU_SET_BINOP(name, op) \
5117 static PyObject * \
5118 do_cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right, Py_cpu_set *res) { \
5119 if (res) { \
5120 Py_INCREF(res); \
5121 } \
5122 else { \
Benjamin Petersone870fe62011-08-02 17:44:26 -05005123 res = make_new_cpu_set(&cpu_set_type, left->ncpus); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005124 if (!res) \
5125 return NULL; \
5126 } \
Benjamin Peterson9b374bf2011-08-02 18:22:30 -05005127 if (Py_TYPE(right) != &cpu_set_type || left->ncpus != right->ncpus) { \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005128 Py_DECREF(res); \
Brian Curtindfc80e32011-08-10 20:28:54 -05005129 Py_RETURN_NOTIMPLEMENTED; \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005130 } \
Benjamin Peterson8f7bdd32011-08-02 18:34:30 -05005131 assert(left->size == right->size && right->size == res->size); \
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005132 op(res->size, res->set, left->set, right->set); \
5133 return (PyObject *)res; \
5134 } \
5135 static PyObject * \
5136 cpu_set_##name(Py_cpu_set *left, Py_cpu_set *right) { \
5137 return do_cpu_set_##name(left, right, NULL); \
5138 } \
5139 static PyObject * \
5140 cpu_set_i##name(Py_cpu_set *left, Py_cpu_set *right) { \
5141 return do_cpu_set_##name(left, right, left); \
5142 } \
5143
5144CPU_SET_BINOP(and, CPU_AND_S)
5145CPU_SET_BINOP(or, CPU_OR_S)
5146CPU_SET_BINOP(xor, CPU_XOR_S)
5147#undef CPU_SET_BINOP
5148
5149PyDoc_STRVAR(cpu_set_doc,
5150"cpu_set(size)\n\n\
5151Create an empty mask of CPUs.");
5152
5153static PyNumberMethods cpu_set_as_number = {
5154 0, /*nb_add*/
5155 0, /*nb_subtract*/
5156 0, /*nb_multiply*/
5157 0, /*nb_remainder*/
5158 0, /*nb_divmod*/
5159 0, /*nb_power*/
5160 0, /*nb_negative*/
5161 0, /*nb_positive*/
5162 0, /*nb_absolute*/
5163 0, /*nb_bool*/
5164 0, /*nb_invert*/
5165 0, /*nb_lshift*/
5166 0, /*nb_rshift*/
5167 (binaryfunc)cpu_set_and, /*nb_and*/
5168 (binaryfunc)cpu_set_xor, /*nb_xor*/
5169 (binaryfunc)cpu_set_or, /*nb_or*/
5170 0, /*nb_int*/
5171 0, /*nb_reserved*/
5172 0, /*nb_float*/
5173 0, /*nb_inplace_add*/
5174 0, /*nb_inplace_subtract*/
5175 0, /*nb_inplace_multiply*/
5176 0, /*nb_inplace_remainder*/
5177 0, /*nb_inplace_power*/
5178 0, /*nb_inplace_lshift*/
5179 0, /*nb_inplace_rshift*/
5180 (binaryfunc)cpu_set_iand, /*nb_inplace_and*/
5181 (binaryfunc)cpu_set_ixor, /*nb_inplace_xor*/
5182 (binaryfunc)cpu_set_ior, /*nb_inplace_or*/
5183};
5184
5185static PySequenceMethods cpu_set_as_sequence = {
5186 (lenfunc)cpu_set_len, /* sq_length */
5187};
5188
5189static PyMethodDef cpu_set_methods[] = {
5190 {"clear", (PyCFunction)cpu_set_clear, METH_VARARGS, cpu_set_clear_doc},
5191 {"count", (PyCFunction)cpu_set_count, METH_NOARGS, cpu_set_count_doc},
5192 {"isset", (PyCFunction)cpu_set_isset, METH_VARARGS, cpu_set_isset_doc},
5193 {"set", (PyCFunction)cpu_set_set, METH_VARARGS, cpu_set_set_doc},
5194 {"zero", (PyCFunction)cpu_set_zero, METH_NOARGS, cpu_set_zero_doc},
5195 {NULL, NULL} /* sentinel */
5196};
5197
5198static PyTypeObject cpu_set_type = {
5199 PyVarObject_HEAD_INIT(&PyType_Type, 0)
5200 "posix.cpu_set", /* tp_name */
5201 sizeof(Py_cpu_set), /* tp_basicsize */
5202 0, /* tp_itemsize */
5203 /* methods */
5204 (destructor)cpu_set_dealloc, /* tp_dealloc */
5205 0, /* tp_print */
5206 0, /* tp_getattr */
5207 0, /* tp_setattr */
5208 0, /* tp_reserved */
5209 (reprfunc)cpu_set_repr, /* tp_repr */
5210 &cpu_set_as_number, /* tp_as_number */
5211 &cpu_set_as_sequence, /* tp_as_sequence */
5212 0, /* tp_as_mapping */
5213 PyObject_HashNotImplemented, /* tp_hash */
5214 0, /* tp_call */
5215 0, /* tp_str */
5216 PyObject_GenericGetAttr, /* tp_getattro */
5217 0, /* tp_setattro */
5218 0, /* tp_as_buffer */
5219 Py_TPFLAGS_DEFAULT, /* tp_flags */
5220 cpu_set_doc, /* tp_doc */
5221 0, /* tp_traverse */
5222 0, /* tp_clear */
5223 (richcmpfunc)cpu_set_richcompare, /* tp_richcompare */
5224 0, /* tp_weaklistoffset */
5225 0, /* tp_iter */
5226 0, /* tp_iternext */
5227 cpu_set_methods, /* tp_methods */
5228 0, /* tp_members */
5229 0, /* tp_getset */
5230 0, /* tp_base */
5231 0, /* tp_dict */
5232 0, /* tp_descr_get */
5233 0, /* tp_descr_set */
5234 0, /* tp_dictoffset */
5235 0, /* tp_init */
5236 PyType_GenericAlloc, /* tp_alloc */
5237 cpu_set_new, /* tp_new */
5238 PyObject_Del, /* tp_free */
5239};
5240
5241PyDoc_STRVAR(posix_sched_setaffinity__doc__,
5242"sched_setaffinity(pid, cpu_set)\n\n\
5243Set the affinity of the process with PID *pid* to *cpu_set*.");
5244
5245static PyObject *
5246posix_sched_setaffinity(PyObject *self, PyObject *args)
5247{
5248 pid_t pid;
5249 Py_cpu_set *cpu_set;
5250
Benjamin Petersona17a5d62011-08-09 16:49:13 -05005251 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O!:sched_setaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005252 &pid, &cpu_set_type, &cpu_set))
5253 return NULL;
5254 if (sched_setaffinity(pid, cpu_set->size, cpu_set->set))
5255 return posix_error();
5256 Py_RETURN_NONE;
5257}
5258
5259PyDoc_STRVAR(posix_sched_getaffinity__doc__,
5260"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\
5261Return the affinity of the process with PID *pid*.\n\
5262The returned cpu_set will be of size *ncpus*.");
5263
5264static PyObject *
5265posix_sched_getaffinity(PyObject *self, PyObject *args)
5266{
5267 pid_t pid;
5268 int ncpus;
5269 Py_cpu_set *res;
5270
Benjamin Peterson7ac92142011-08-03 08:54:26 -05005271 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:sched_getaffinity",
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005272 &pid, &ncpus))
5273 return NULL;
5274 res = make_new_cpu_set(&cpu_set_type, ncpus);
5275 if (!res)
5276 return NULL;
5277 if (sched_getaffinity(pid, res->size, res->set)) {
5278 Py_DECREF(res);
5279 return posix_error();
5280 }
5281 return (PyObject *)res;
5282}
5283
Benjamin Peterson2740af82011-08-02 17:41:34 -05005284#endif /* HAVE_SCHED_SETAFFINITY */
5285
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005286#endif /* HAVE_SCHED_H */
5287
Neal Norwitzb59798b2003-03-21 01:43:31 +00005288/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005289/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5290#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005291#define DEV_PTY_FILE "/dev/ptc"
5292#define HAVE_DEV_PTMX
5293#else
5294#define DEV_PTY_FILE "/dev/ptmx"
5295#endif
5296
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005297#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005298#ifdef HAVE_PTY_H
5299#include <pty.h>
5300#else
5301#ifdef HAVE_LIBUTIL_H
5302#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005303#else
5304#ifdef HAVE_UTIL_H
5305#include <util.h>
5306#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005307#endif /* HAVE_LIBUTIL_H */
5308#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005309#ifdef HAVE_STROPTS_H
5310#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005311#endif
5312#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005313
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005314#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005315PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005316"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005317Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005318
5319static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005320posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005321{
Victor Stinner8c62be82010-05-06 00:08:46 +00005322 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005323#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005324 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005325#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005326#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005328#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005329 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005330#endif
5331#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005332
Thomas Wouters70c21a12000-07-14 14:28:33 +00005333#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
5335 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005336#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5338 if (slave_name == NULL)
5339 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00005340
Victor Stinner8c62be82010-05-06 00:08:46 +00005341 slave_fd = open(slave_name, O_RDWR);
5342 if (slave_fd < 0)
5343 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005344#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005345 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
5346 if (master_fd < 0)
5347 return posix_error();
5348 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
5349 /* change permission of slave */
5350 if (grantpt(master_fd) < 0) {
5351 PyOS_setsig(SIGCHLD, sig_saved);
5352 return posix_error();
5353 }
5354 /* unlock slave */
5355 if (unlockpt(master_fd) < 0) {
5356 PyOS_setsig(SIGCHLD, sig_saved);
5357 return posix_error();
5358 }
5359 PyOS_setsig(SIGCHLD, sig_saved);
5360 slave_name = ptsname(master_fd); /* get name of slave */
5361 if (slave_name == NULL)
5362 return posix_error();
5363 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
5364 if (slave_fd < 0)
5365 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00005366#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005367 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5368 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005369#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005371#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005372#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005373#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005374
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005376
Fred Drake8cef4cf2000-06-28 16:40:38 +00005377}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005378#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005379
5380#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005381PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005382"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00005383Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
5384Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005385To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00005386
5387static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005388posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005389{
Victor Stinner8c62be82010-05-06 00:08:46 +00005390 int master_fd = -1, result = 0;
5391 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005392
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 _PyImport_AcquireLock();
5394 pid = forkpty(&master_fd, NULL, NULL, NULL);
5395 if (pid == 0) {
5396 /* child: this clobbers and resets the import lock. */
5397 PyOS_AfterFork();
5398 } else {
5399 /* parent: release the import lock. */
5400 result = _PyImport_ReleaseLock();
5401 }
5402 if (pid == -1)
5403 return posix_error();
5404 if (result < 0) {
5405 /* Don't clobber the OSError if the fork failed. */
5406 PyErr_SetString(PyExc_RuntimeError,
5407 "not holding the import lock");
5408 return NULL;
5409 }
5410 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005411}
5412#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005413
Ross Lagerwall7807c352011-03-17 20:20:30 +02005414
Guido van Rossumad0ee831995-03-01 10:34:45 +00005415#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005416PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005417"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005418Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005419
Barry Warsaw53699e91996-12-10 23:23:01 +00005420static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005421posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005422{
Victor Stinner8c62be82010-05-06 00:08:46 +00005423 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005424}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005425#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005426
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005427
Guido van Rossumad0ee831995-03-01 10:34:45 +00005428#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005429PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005430"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005431Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005432
Barry Warsaw53699e91996-12-10 23:23:01 +00005433static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005434posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005435{
Victor Stinner8c62be82010-05-06 00:08:46 +00005436 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005437}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005438#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005440
Guido van Rossumad0ee831995-03-01 10:34:45 +00005441#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005442PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005443"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005445
Barry Warsaw53699e91996-12-10 23:23:01 +00005446static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005447posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005448{
Victor Stinner8c62be82010-05-06 00:08:46 +00005449 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005450}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005451#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005453
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005454PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005455"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005456Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005457
Barry Warsaw53699e91996-12-10 23:23:01 +00005458static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005459posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005460{
Victor Stinner8c62be82010-05-06 00:08:46 +00005461 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005462}
5463
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005464#ifdef HAVE_GETGROUPLIST
5465PyDoc_STRVAR(posix_getgrouplist__doc__,
5466"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5467Returns a list of groups to which a user belongs.\n\n\
5468 user: username to lookup\n\
5469 group: base group id of the user");
5470
5471static PyObject *
5472posix_getgrouplist(PyObject *self, PyObject *args)
5473{
5474#ifdef NGROUPS_MAX
5475#define MAX_GROUPS NGROUPS_MAX
5476#else
5477 /* defined to be 16 on Solaris7, so this should be a small number */
5478#define MAX_GROUPS 64
5479#endif
5480
5481 const char *user;
5482 int i, ngroups;
5483 PyObject *list;
5484#ifdef __APPLE__
5485 int *groups, basegid;
5486#else
5487 gid_t *groups, basegid;
5488#endif
5489 ngroups = MAX_GROUPS;
5490
5491 if (!PyArg_ParseTuple(args, "si", &user, &basegid))
5492 return NULL;
5493
5494#ifdef __APPLE__
5495 groups = PyMem_Malloc(ngroups * sizeof(int));
5496#else
5497 groups = PyMem_Malloc(ngroups * sizeof(gid_t));
5498#endif
5499 if (groups == NULL)
5500 return PyErr_NoMemory();
5501
5502 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5503 PyMem_Del(groups);
5504 return posix_error();
5505 }
5506
5507 list = PyList_New(ngroups);
5508 if (list == NULL) {
5509 PyMem_Del(groups);
5510 return NULL;
5511 }
5512
5513 for (i = 0; i < ngroups; i++) {
5514 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
5515 if (o == NULL) {
5516 Py_DECREF(list);
5517 PyMem_Del(groups);
5518 return NULL;
5519 }
5520 PyList_SET_ITEM(list, i, o);
5521 }
5522
5523 PyMem_Del(groups);
5524
5525 return list;
5526}
5527#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005528
Fred Drakec9680921999-12-13 16:37:25 +00005529#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005530PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005531"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005532Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00005533
5534static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005535posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00005536{
5537 PyObject *result = NULL;
5538
Fred Drakec9680921999-12-13 16:37:25 +00005539#ifdef NGROUPS_MAX
5540#define MAX_GROUPS NGROUPS_MAX
5541#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005542 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005543#define MAX_GROUPS 64
5544#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005546
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005547 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005548 * This is a helper variable to store the intermediate result when
5549 * that happens.
5550 *
5551 * To keep the code readable the OSX behaviour is unconditional,
5552 * according to the POSIX spec this should be safe on all unix-y
5553 * systems.
5554 */
5555 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005556 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005557
Victor Stinner8c62be82010-05-06 00:08:46 +00005558 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005559 if (n < 0) {
5560 if (errno == EINVAL) {
5561 n = getgroups(0, NULL);
5562 if (n == -1) {
5563 return posix_error();
5564 }
5565 if (n == 0) {
5566 /* Avoid malloc(0) */
5567 alt_grouplist = grouplist;
5568 } else {
5569 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
5570 if (alt_grouplist == NULL) {
5571 errno = EINVAL;
5572 return posix_error();
5573 }
5574 n = getgroups(n, alt_grouplist);
5575 if (n == -1) {
5576 PyMem_Free(alt_grouplist);
5577 return posix_error();
5578 }
5579 }
5580 } else {
5581 return posix_error();
5582 }
5583 }
5584 result = PyList_New(n);
5585 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005586 int i;
5587 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005588 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00005589 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00005590 Py_DECREF(result);
5591 result = NULL;
5592 break;
Fred Drakec9680921999-12-13 16:37:25 +00005593 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005594 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00005595 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005596 }
5597
5598 if (alt_grouplist != grouplist) {
5599 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005600 }
Neal Norwitze241ce82003-02-17 18:17:05 +00005601
Fred Drakec9680921999-12-13 16:37:25 +00005602 return result;
5603}
5604#endif
5605
Antoine Pitroub7572f02009-12-02 20:46:48 +00005606#ifdef HAVE_INITGROUPS
5607PyDoc_STRVAR(posix_initgroups__doc__,
5608"initgroups(username, gid) -> None\n\n\
5609Call the system initgroups() to initialize the group access list with all of\n\
5610the groups of which the specified username is a member, plus the specified\n\
5611group id.");
5612
5613static PyObject *
5614posix_initgroups(PyObject *self, PyObject *args)
5615{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005616 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00005617 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005618 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00005619 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005620
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005621 if (!PyArg_ParseTuple(args, "O&l:initgroups",
5622 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00005623 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005624 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005625
Victor Stinner61ec5dc2010-08-15 09:22:44 +00005626 res = initgroups(username, (gid_t) gid);
5627 Py_DECREF(oname);
5628 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00005629 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00005630
Victor Stinner8c62be82010-05-06 00:08:46 +00005631 Py_INCREF(Py_None);
5632 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00005633}
5634#endif
5635
Martin v. Löwis606edc12002-06-13 21:09:11 +00005636#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005637PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005638"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00005639Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00005640
5641static PyObject *
5642posix_getpgid(PyObject *self, PyObject *args)
5643{
Victor Stinner8c62be82010-05-06 00:08:46 +00005644 pid_t pid, pgid;
5645 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
5646 return NULL;
5647 pgid = getpgid(pid);
5648 if (pgid < 0)
5649 return posix_error();
5650 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00005651}
5652#endif /* HAVE_GETPGID */
5653
5654
Guido van Rossumb6775db1994-08-01 11:34:53 +00005655#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005656PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005657"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005658Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005659
Barry Warsaw53699e91996-12-10 23:23:01 +00005660static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005661posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00005662{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005663#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005664 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005665#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005666 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005667#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00005668}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005669#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00005670
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005671
Guido van Rossumb6775db1994-08-01 11:34:53 +00005672#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005673PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005674"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00005675Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005676
Barry Warsaw53699e91996-12-10 23:23:01 +00005677static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005678posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005679{
Guido van Rossum64933891994-10-20 21:56:42 +00005680#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00005681 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005682#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005683 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00005684#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00005685 return posix_error();
5686 Py_INCREF(Py_None);
5687 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005688}
5689
Guido van Rossumb6775db1994-08-01 11:34:53 +00005690#endif /* HAVE_SETPGRP */
5691
Guido van Rossumad0ee831995-03-01 10:34:45 +00005692#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005693
5694#ifdef MS_WINDOWS
5695#include <tlhelp32.h>
5696
5697static PyObject*
5698win32_getppid()
5699{
5700 HANDLE snapshot;
5701 pid_t mypid;
5702 PyObject* result = NULL;
5703 BOOL have_record;
5704 PROCESSENTRY32 pe;
5705
5706 mypid = getpid(); /* This function never fails */
5707
5708 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5709 if (snapshot == INVALID_HANDLE_VALUE)
5710 return PyErr_SetFromWindowsErr(GetLastError());
5711
5712 pe.dwSize = sizeof(pe);
5713 have_record = Process32First(snapshot, &pe);
5714 while (have_record) {
5715 if (mypid == (pid_t)pe.th32ProcessID) {
5716 /* We could cache the ulong value in a static variable. */
5717 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
5718 break;
5719 }
5720
5721 have_record = Process32Next(snapshot, &pe);
5722 }
5723
5724 /* If our loop exits and our pid was not found (result will be NULL)
5725 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
5726 * error anyway, so let's raise it. */
5727 if (!result)
5728 result = PyErr_SetFromWindowsErr(GetLastError());
5729
5730 CloseHandle(snapshot);
5731
5732 return result;
5733}
5734#endif /*MS_WINDOWS*/
5735
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005737"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005738Return the parent's process id. If the parent process has already exited,\n\
5739Windows machines will still return its id; others systems will return the id\n\
5740of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005741
Barry Warsaw53699e91996-12-10 23:23:01 +00005742static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005743posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005744{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005745#ifdef MS_WINDOWS
5746 return win32_getppid();
5747#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005748 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00005749#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00005750}
5751#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00005752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005753
Fred Drake12c6e2d1999-12-14 21:25:03 +00005754#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005755PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005756"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005757Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00005758
5759static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005760posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005761{
Victor Stinner8c62be82010-05-06 00:08:46 +00005762 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005763#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005764 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02005765 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005766
5767 if (GetUserNameW(user_name, &num_chars)) {
5768 /* num_chars is the number of unicode chars plus null terminator */
5769 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005770 }
5771 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005772 result = PyErr_SetFromWindowsErr(GetLastError());
5773#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005774 char *name;
5775 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005776
Victor Stinner8c62be82010-05-06 00:08:46 +00005777 errno = 0;
5778 name = getlogin();
5779 if (name == NULL) {
5780 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00005781 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00005782 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005783 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00005784 }
5785 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00005786 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00005787 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005788#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00005789 return result;
5790}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00005791#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005792
Guido van Rossumad0ee831995-03-01 10:34:45 +00005793#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005794PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005795"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005796Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005797
Barry Warsaw53699e91996-12-10 23:23:01 +00005798static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005799posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00005800{
Victor Stinner8c62be82010-05-06 00:08:46 +00005801 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005802}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005803#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00005804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005805
Guido van Rossumad0ee831995-03-01 10:34:45 +00005806#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005807PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005808"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005809Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005810
Barry Warsaw53699e91996-12-10 23:23:01 +00005811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005812posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005813{
Victor Stinner8c62be82010-05-06 00:08:46 +00005814 pid_t pid;
5815 int sig;
5816 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
5817 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005818#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005819 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
5820 APIRET rc;
5821 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005822 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005823
5824 } else if (sig == XCPT_SIGNAL_KILLPROC) {
5825 APIRET rc;
5826 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005827 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005828
5829 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005830 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005831#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 if (kill(pid, sig) == -1)
5833 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005834#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005835 Py_INCREF(Py_None);
5836 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00005837}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005838#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005839
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005840#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005841PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005842"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005843Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005844
5845static PyObject *
5846posix_killpg(PyObject *self, PyObject *args)
5847{
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 int sig;
5849 pid_t pgid;
5850 /* XXX some man pages make the `pgid` parameter an int, others
5851 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
5852 take the same type. Moreover, pid_t is always at least as wide as
5853 int (else compilation of this module fails), which is safe. */
5854 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
5855 return NULL;
5856 if (killpg(pgid, sig) == -1)
5857 return posix_error();
5858 Py_INCREF(Py_None);
5859 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005860}
5861#endif
5862
Brian Curtineb24d742010-04-12 17:16:38 +00005863#ifdef MS_WINDOWS
5864PyDoc_STRVAR(win32_kill__doc__,
5865"kill(pid, sig)\n\n\
5866Kill a process with a signal.");
5867
5868static PyObject *
5869win32_kill(PyObject *self, PyObject *args)
5870{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00005871 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00005872 DWORD pid, sig, err;
5873 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00005874
Victor Stinner8c62be82010-05-06 00:08:46 +00005875 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
5876 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00005877
Victor Stinner8c62be82010-05-06 00:08:46 +00005878 /* Console processes which share a common console can be sent CTRL+C or
5879 CTRL+BREAK events, provided they handle said events. */
5880 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
5881 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
5882 err = GetLastError();
5883 PyErr_SetFromWindowsErr(err);
5884 }
5885 else
5886 Py_RETURN_NONE;
5887 }
Brian Curtineb24d742010-04-12 17:16:38 +00005888
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
5890 attempt to open and terminate the process. */
5891 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
5892 if (handle == NULL) {
5893 err = GetLastError();
5894 return PyErr_SetFromWindowsErr(err);
5895 }
Brian Curtineb24d742010-04-12 17:16:38 +00005896
Victor Stinner8c62be82010-05-06 00:08:46 +00005897 if (TerminateProcess(handle, sig) == 0) {
5898 err = GetLastError();
5899 result = PyErr_SetFromWindowsErr(err);
5900 } else {
5901 Py_INCREF(Py_None);
5902 result = Py_None;
5903 }
Brian Curtineb24d742010-04-12 17:16:38 +00005904
Victor Stinner8c62be82010-05-06 00:08:46 +00005905 CloseHandle(handle);
5906 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00005907}
5908#endif /* MS_WINDOWS */
5909
Guido van Rossumc0125471996-06-28 18:55:32 +00005910#ifdef HAVE_PLOCK
5911
5912#ifdef HAVE_SYS_LOCK_H
5913#include <sys/lock.h>
5914#endif
5915
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005916PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005917"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005918Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005919
Barry Warsaw53699e91996-12-10 23:23:01 +00005920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005921posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00005922{
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 int op;
5924 if (!PyArg_ParseTuple(args, "i:plock", &op))
5925 return NULL;
5926 if (plock(op) == -1)
5927 return posix_error();
5928 Py_INCREF(Py_None);
5929 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00005930}
5931#endif
5932
Guido van Rossumb6775db1994-08-01 11:34:53 +00005933#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005934PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005935"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005936Set the current process's user id.");
5937
Barry Warsaw53699e91996-12-10 23:23:01 +00005938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005939posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005940{
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 long uid_arg;
5942 uid_t uid;
5943 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5944 return NULL;
5945 uid = uid_arg;
5946 if (uid != uid_arg) {
5947 PyErr_SetString(PyExc_OverflowError, "user id too big");
5948 return NULL;
5949 }
5950 if (setuid(uid) < 0)
5951 return posix_error();
5952 Py_INCREF(Py_None);
5953 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005954}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005955#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005957
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005958#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005959PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005960"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005961Set the current process's effective user id.");
5962
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005963static PyObject *
5964posix_seteuid (PyObject *self, PyObject *args)
5965{
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 long euid_arg;
5967 uid_t euid;
5968 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5969 return NULL;
5970 euid = euid_arg;
5971 if (euid != euid_arg) {
5972 PyErr_SetString(PyExc_OverflowError, "user id too big");
5973 return NULL;
5974 }
5975 if (seteuid(euid) < 0) {
5976 return posix_error();
5977 } else {
5978 Py_INCREF(Py_None);
5979 return Py_None;
5980 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005981}
5982#endif /* HAVE_SETEUID */
5983
5984#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005985PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005986"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005987Set the current process's effective group id.");
5988
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005989static PyObject *
5990posix_setegid (PyObject *self, PyObject *args)
5991{
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 long egid_arg;
5993 gid_t egid;
5994 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5995 return NULL;
5996 egid = egid_arg;
5997 if (egid != egid_arg) {
5998 PyErr_SetString(PyExc_OverflowError, "group id too big");
5999 return NULL;
6000 }
6001 if (setegid(egid) < 0) {
6002 return posix_error();
6003 } else {
6004 Py_INCREF(Py_None);
6005 return Py_None;
6006 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006007}
6008#endif /* HAVE_SETEGID */
6009
6010#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006012"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013Set the current process's real and effective user ids.");
6014
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006015static PyObject *
6016posix_setreuid (PyObject *self, PyObject *args)
6017{
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 long ruid_arg, euid_arg;
6019 uid_t ruid, euid;
6020 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
6021 return NULL;
6022 if (ruid_arg == -1)
6023 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
6024 else
6025 ruid = ruid_arg; /* otherwise, assign from our long */
6026 if (euid_arg == -1)
6027 euid = (uid_t)-1;
6028 else
6029 euid = euid_arg;
6030 if ((euid_arg != -1 && euid != euid_arg) ||
6031 (ruid_arg != -1 && ruid != ruid_arg)) {
6032 PyErr_SetString(PyExc_OverflowError, "user id too big");
6033 return NULL;
6034 }
6035 if (setreuid(ruid, euid) < 0) {
6036 return posix_error();
6037 } else {
6038 Py_INCREF(Py_None);
6039 return Py_None;
6040 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006041}
6042#endif /* HAVE_SETREUID */
6043
6044#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006045PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006046"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047Set the current process's real and effective group ids.");
6048
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006049static PyObject *
6050posix_setregid (PyObject *self, PyObject *args)
6051{
Victor Stinner8c62be82010-05-06 00:08:46 +00006052 long rgid_arg, egid_arg;
6053 gid_t rgid, egid;
6054 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
6055 return NULL;
6056 if (rgid_arg == -1)
6057 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
6058 else
6059 rgid = rgid_arg; /* otherwise, assign from our long */
6060 if (egid_arg == -1)
6061 egid = (gid_t)-1;
6062 else
6063 egid = egid_arg;
6064 if ((egid_arg != -1 && egid != egid_arg) ||
6065 (rgid_arg != -1 && rgid != rgid_arg)) {
6066 PyErr_SetString(PyExc_OverflowError, "group id too big");
6067 return NULL;
6068 }
6069 if (setregid(rgid, egid) < 0) {
6070 return posix_error();
6071 } else {
6072 Py_INCREF(Py_None);
6073 return Py_None;
6074 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006075}
6076#endif /* HAVE_SETREGID */
6077
Guido van Rossumb6775db1994-08-01 11:34:53 +00006078#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006082
Barry Warsaw53699e91996-12-10 23:23:01 +00006083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006084posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006085{
Victor Stinner8c62be82010-05-06 00:08:46 +00006086 long gid_arg;
6087 gid_t gid;
6088 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
6089 return NULL;
6090 gid = gid_arg;
6091 if (gid != gid_arg) {
6092 PyErr_SetString(PyExc_OverflowError, "group id too big");
6093 return NULL;
6094 }
6095 if (setgid(gid) < 0)
6096 return posix_error();
6097 Py_INCREF(Py_None);
6098 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006099}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006100#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006101
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006102#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006103PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006104"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006106
6107static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006108posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006109{
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 int i, len;
6111 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006112
Victor Stinner8c62be82010-05-06 00:08:46 +00006113 if (!PySequence_Check(groups)) {
6114 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6115 return NULL;
6116 }
6117 len = PySequence_Size(groups);
6118 if (len > MAX_GROUPS) {
6119 PyErr_SetString(PyExc_ValueError, "too many groups");
6120 return NULL;
6121 }
6122 for(i = 0; i < len; i++) {
6123 PyObject *elem;
6124 elem = PySequence_GetItem(groups, i);
6125 if (!elem)
6126 return NULL;
6127 if (!PyLong_Check(elem)) {
6128 PyErr_SetString(PyExc_TypeError,
6129 "groups must be integers");
6130 Py_DECREF(elem);
6131 return NULL;
6132 } else {
6133 unsigned long x = PyLong_AsUnsignedLong(elem);
6134 if (PyErr_Occurred()) {
6135 PyErr_SetString(PyExc_TypeError,
6136 "group id too big");
6137 Py_DECREF(elem);
6138 return NULL;
6139 }
6140 grouplist[i] = x;
6141 /* read back the value to see if it fitted in gid_t */
6142 if (grouplist[i] != x) {
6143 PyErr_SetString(PyExc_TypeError,
6144 "group id too big");
6145 Py_DECREF(elem);
6146 return NULL;
6147 }
6148 }
6149 Py_DECREF(elem);
6150 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006151
Victor Stinner8c62be82010-05-06 00:08:46 +00006152 if (setgroups(len, grouplist) < 0)
6153 return posix_error();
6154 Py_INCREF(Py_None);
6155 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006156}
6157#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006158
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006159#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6160static PyObject *
Victor Stinnerccd57152012-02-08 14:31:50 +01006161wait_helper(pid_t pid, int status, struct rusage *ru, PyObject *timestamp)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006162{
Victor Stinner8c62be82010-05-06 00:08:46 +00006163 PyObject *result;
6164 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006165 _Py_IDENTIFIER(struct_rusage);
Victor Stinnerccd57152012-02-08 14:31:50 +01006166 _PyTime_t ts;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006167
Victor Stinner8c62be82010-05-06 00:08:46 +00006168 if (pid == -1)
6169 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006170
Victor Stinner8c62be82010-05-06 00:08:46 +00006171 if (struct_rusage == NULL) {
6172 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6173 if (m == NULL)
6174 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006175 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 Py_DECREF(m);
6177 if (struct_rusage == NULL)
6178 return NULL;
6179 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006180
Victor Stinner8c62be82010-05-06 00:08:46 +00006181 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6182 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6183 if (!result)
6184 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006185
6186#ifndef doubletime
6187#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6188#endif
6189
Victor Stinnerccd57152012-02-08 14:31:50 +01006190 ts.seconds = ru->ru_utime.tv_sec;
6191 ts.numerator = ru->ru_utime.tv_usec;
6192 ts.denominator = 1000000;
Victor Stinner8c62be82010-05-06 00:08:46 +00006193 PyStructSequence_SET_ITEM(result, 0,
Victor Stinnerccd57152012-02-08 14:31:50 +01006194 _PyTime_Convert(&ts, timestamp));
6195
6196 ts.seconds = ru->ru_stime.tv_sec;
6197 ts.numerator = ru->ru_stime.tv_usec;
6198 ts.denominator = 1000000;
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 PyStructSequence_SET_ITEM(result, 1,
Victor Stinnerccd57152012-02-08 14:31:50 +01006200 _PyTime_Convert(&ts, timestamp));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006201#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6203 SET_INT(result, 2, ru->ru_maxrss);
6204 SET_INT(result, 3, ru->ru_ixrss);
6205 SET_INT(result, 4, ru->ru_idrss);
6206 SET_INT(result, 5, ru->ru_isrss);
6207 SET_INT(result, 6, ru->ru_minflt);
6208 SET_INT(result, 7, ru->ru_majflt);
6209 SET_INT(result, 8, ru->ru_nswap);
6210 SET_INT(result, 9, ru->ru_inblock);
6211 SET_INT(result, 10, ru->ru_oublock);
6212 SET_INT(result, 11, ru->ru_msgsnd);
6213 SET_INT(result, 12, ru->ru_msgrcv);
6214 SET_INT(result, 13, ru->ru_nsignals);
6215 SET_INT(result, 14, ru->ru_nvcsw);
6216 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006217#undef SET_INT
6218
Victor Stinner8c62be82010-05-06 00:08:46 +00006219 if (PyErr_Occurred()) {
6220 Py_DECREF(result);
6221 return NULL;
6222 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006223
Victor Stinner8c62be82010-05-06 00:08:46 +00006224 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006225}
6226#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6227
6228#ifdef HAVE_WAIT3
6229PyDoc_STRVAR(posix_wait3__doc__,
Victor Stinnerccd57152012-02-08 14:31:50 +01006230"wait3(options[, timestamp=float]) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006231Wait for completion of a child process.");
6232
6233static PyObject *
Victor Stinnerccd57152012-02-08 14:31:50 +01006234posix_wait3(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006235{
Victor Stinnerccd57152012-02-08 14:31:50 +01006236 static char *kwlist[] = {"options", "timestamp", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +00006237 pid_t pid;
6238 int options;
6239 struct rusage ru;
6240 WAIT_TYPE status;
6241 WAIT_STATUS_INT(status) = 0;
Victor Stinnerccd57152012-02-08 14:31:50 +01006242 PyObject *timestamp = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006243
Victor Stinnerccd57152012-02-08 14:31:50 +01006244 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|O:wait3", kwlist, &options, &timestamp))
Victor Stinner8c62be82010-05-06 00:08:46 +00006245 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006246
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 Py_BEGIN_ALLOW_THREADS
6248 pid = wait3(&status, options, &ru);
6249 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006250
Victor Stinnerccd57152012-02-08 14:31:50 +01006251 return wait_helper(pid, WAIT_STATUS_INT(status), &ru, timestamp);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006252}
6253#endif /* HAVE_WAIT3 */
6254
6255#ifdef HAVE_WAIT4
6256PyDoc_STRVAR(posix_wait4__doc__,
Victor Stinnerccd57152012-02-08 14:31:50 +01006257"wait4(pid, options[, timestamp=float]) -> (pid, status, rusage)\n\n\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006258Wait for completion of a given child process.");
6259
6260static PyObject *
Victor Stinnerccd57152012-02-08 14:31:50 +01006261posix_wait4(PyObject *self, PyObject *args, PyObject *kwargs)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006262{
Victor Stinnerccd57152012-02-08 14:31:50 +01006263 static char *kwlist[] = {"pid", "options", "timestamp", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +00006264 pid_t pid;
6265 int options;
6266 struct rusage ru;
6267 WAIT_TYPE status;
6268 WAIT_STATUS_INT(status) = 0;
Victor Stinnerccd57152012-02-08 14:31:50 +01006269 PyObject *timestamp = NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006270
Victor Stinnerccd57152012-02-08 14:31:50 +01006271 if (!PyArg_ParseTupleAndKeywords(args, kwargs, _Py_PARSE_PID "i|O:wait4", kwlist, &pid, &options, &timestamp))
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006273
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 Py_BEGIN_ALLOW_THREADS
6275 pid = wait4(pid, &status, options, &ru);
6276 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006277
Victor Stinnerccd57152012-02-08 14:31:50 +01006278 return wait_helper(pid, WAIT_STATUS_INT(status), &ru, timestamp);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006279}
6280#endif /* HAVE_WAIT4 */
6281
Ross Lagerwall7807c352011-03-17 20:20:30 +02006282#if defined(HAVE_WAITID) && !defined(__APPLE__)
6283PyDoc_STRVAR(posix_waitid__doc__,
6284"waitid(idtype, id, options) -> waitid_result\n\n\
6285Wait for the completion of one or more child processes.\n\n\
6286idtype can be P_PID, P_PGID or P_ALL.\n\
6287id specifies the pid to wait on.\n\
6288options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\
6289or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\
6290Returns either waitid_result or None if WNOHANG is specified and there are\n\
6291no children in a waitable state.");
6292
6293static PyObject *
6294posix_waitid(PyObject *self, PyObject *args)
6295{
6296 PyObject *result;
6297 idtype_t idtype;
6298 id_t id;
6299 int options, res;
6300 siginfo_t si;
6301 si.si_pid = 0;
6302 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options))
6303 return NULL;
6304 Py_BEGIN_ALLOW_THREADS
6305 res = waitid(idtype, id, &si, options);
6306 Py_END_ALLOW_THREADS
6307 if (res == -1)
6308 return posix_error();
6309
6310 if (si.si_pid == 0)
6311 Py_RETURN_NONE;
6312
6313 result = PyStructSequence_New(&WaitidResultType);
6314 if (!result)
6315 return NULL;
6316
6317 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
6318 PyStructSequence_SET_ITEM(result, 1, PyLong_FromPid(si.si_uid));
6319 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6320 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6321 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6322 if (PyErr_Occurred()) {
6323 Py_DECREF(result);
6324 return NULL;
6325 }
6326
6327 return result;
6328}
6329#endif
6330
Guido van Rossumb6775db1994-08-01 11:34:53 +00006331#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006332PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006333"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006334Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006335
Barry Warsaw53699e91996-12-10 23:23:01 +00006336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006337posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006338{
Victor Stinner8c62be82010-05-06 00:08:46 +00006339 pid_t pid;
6340 int options;
6341 WAIT_TYPE status;
6342 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006343
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6345 return NULL;
6346 Py_BEGIN_ALLOW_THREADS
6347 pid = waitpid(pid, &status, options);
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 Rossum21803b81992-08-09 12:55:27 +00006353}
6354
Tim Petersab034fa2002-02-01 11:27:43 +00006355#elif defined(HAVE_CWAIT)
6356
6357/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006358PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006359"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006360"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006361
6362static PyObject *
6363posix_waitpid(PyObject *self, PyObject *args)
6364{
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 Py_intptr_t pid;
6366 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006367
Victor Stinner8c62be82010-05-06 00:08:46 +00006368 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
6369 return NULL;
6370 Py_BEGIN_ALLOW_THREADS
6371 pid = _cwait(&status, pid, options);
6372 Py_END_ALLOW_THREADS
6373 if (pid == -1)
6374 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006375
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 /* shift the status left a byte so this is more like the POSIX waitpid */
6377 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006378}
6379#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006380
Guido van Rossumad0ee831995-03-01 10:34:45 +00006381#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006382PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006383"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006384Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006385
Barry Warsaw53699e91996-12-10 23:23:01 +00006386static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006387posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006388{
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 pid_t pid;
6390 WAIT_TYPE status;
6391 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006392
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 Py_BEGIN_ALLOW_THREADS
6394 pid = wait(&status);
6395 Py_END_ALLOW_THREADS
6396 if (pid == -1)
6397 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006398
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006400}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006401#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006402
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006403
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006404PyDoc_STRVAR(posix_lstat__doc__,
Victor Stinnerccd57152012-02-08 14:31:50 +01006405"lstat(path, timestamp=None) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006406Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006407
Barry Warsaw53699e91996-12-10 23:23:01 +00006408static PyObject *
Victor Stinnerccd57152012-02-08 14:31:50 +01006409posix_lstat(PyObject *self, PyObject *args, PyObject *kw)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006410{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006411#ifdef HAVE_LSTAT
Victor Stinnerccd57152012-02-08 14:31:50 +01006412 return posix_do_stat(self, args, kw, "O&|O:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006413#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006414#ifdef MS_WINDOWS
Victor Stinnerccd57152012-02-08 14:31:50 +01006415 return posix_do_stat(self, args, kw, "O&|O:lstat", win32_lstat, "U|O:lstat",
Brian Curtind40e6f72010-07-08 21:39:08 +00006416 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006417#else
Victor Stinnerccd57152012-02-08 14:31:50 +01006418 return posix_do_stat(self, args, "kw, O&|O:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006419#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006420#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006421}
6422
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006423
Guido van Rossumb6775db1994-08-01 11:34:53 +00006424#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006425PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006426"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006427Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006428
Barry Warsaw53699e91996-12-10 23:23:01 +00006429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006430posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006431{
Victor Stinner8c62be82010-05-06 00:08:46 +00006432 PyObject* v;
6433 char buf[MAXPATHLEN];
6434 PyObject *opath;
6435 char *path;
6436 int n;
6437 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006438
Victor Stinner8c62be82010-05-06 00:08:46 +00006439 if (!PyArg_ParseTuple(args, "O&:readlink",
6440 PyUnicode_FSConverter, &opath))
6441 return NULL;
6442 path = PyBytes_AsString(opath);
6443 v = PySequence_GetItem(args, 0);
6444 if (v == NULL) {
6445 Py_DECREF(opath);
6446 return NULL;
6447 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00006448
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 if (PyUnicode_Check(v)) {
6450 arg_is_unicode = 1;
6451 }
6452 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006453
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 Py_BEGIN_ALLOW_THREADS
6455 n = readlink(path, buf, (int) sizeof buf);
6456 Py_END_ALLOW_THREADS
6457 if (n < 0)
6458 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00006459
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00006461 if (arg_is_unicode)
6462 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
6463 else
6464 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006465}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006466#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006468
Brian Curtin52173d42010-12-02 18:29:18 +00006469#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006470PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006471"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006472Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006473
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006475posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006476{
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006478}
6479#endif /* HAVE_SYMLINK */
6480
Brian Curtind40e6f72010-07-08 21:39:08 +00006481#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6482
6483PyDoc_STRVAR(win_readlink__doc__,
6484"readlink(path) -> path\n\n\
6485Return a string representing the path to which the symbolic link points.");
6486
Brian Curtind40e6f72010-07-08 21:39:08 +00006487/* Windows readlink implementation */
6488static PyObject *
6489win_readlink(PyObject *self, PyObject *args)
6490{
6491 wchar_t *path;
6492 DWORD n_bytes_returned;
6493 DWORD io_result;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006494 PyObject *po, *result;
Brian Curtind40e6f72010-07-08 21:39:08 +00006495 HANDLE reparse_point_handle;
6496
6497 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6498 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
6499 wchar_t *print_name;
6500
6501 if (!PyArg_ParseTuple(args,
Victor Stinnereb5657a2011-09-30 01:44:27 +02006502 "U:readlink",
6503 &po))
6504 return NULL;
6505 path = PyUnicode_AsUnicode(po);
6506 if (path == NULL)
Brian Curtind40e6f72010-07-08 21:39:08 +00006507 return NULL;
6508
6509 /* First get a handle to the reparse point */
6510 Py_BEGIN_ALLOW_THREADS
6511 reparse_point_handle = CreateFileW(
6512 path,
6513 0,
6514 0,
6515 0,
6516 OPEN_EXISTING,
6517 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6518 0);
6519 Py_END_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006520
Brian Curtind40e6f72010-07-08 21:39:08 +00006521 if (reparse_point_handle==INVALID_HANDLE_VALUE)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006522 return win32_error_object("readlink", po);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006523
Brian Curtind40e6f72010-07-08 21:39:08 +00006524 Py_BEGIN_ALLOW_THREADS
6525 /* New call DeviceIoControl to read the reparse point */
6526 io_result = DeviceIoControl(
6527 reparse_point_handle,
6528 FSCTL_GET_REPARSE_POINT,
6529 0, 0, /* in buffer */
6530 target_buffer, sizeof(target_buffer),
6531 &n_bytes_returned,
6532 0 /* we're not using OVERLAPPED_IO */
6533 );
6534 CloseHandle(reparse_point_handle);
6535 Py_END_ALLOW_THREADS
6536
6537 if (io_result==0)
Victor Stinnereb5657a2011-09-30 01:44:27 +02006538 return win32_error_object("readlink", po);
Brian Curtind40e6f72010-07-08 21:39:08 +00006539
6540 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
6541 {
6542 PyErr_SetString(PyExc_ValueError,
6543 "not a symbolic link");
6544 return NULL;
6545 }
Brian Curtin74e45612010-07-09 15:58:59 +00006546 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
6547 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
6548
6549 result = PyUnicode_FromWideChar(print_name,
6550 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00006551 return result;
6552}
6553
6554#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
6555
Brian Curtin52173d42010-12-02 18:29:18 +00006556#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtind40e6f72010-07-08 21:39:08 +00006557
6558/* Grab CreateSymbolicLinkW dynamically from kernel32 */
6559static int has_CreateSymbolicLinkW = 0;
6560static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
6561static int
6562check_CreateSymbolicLinkW()
6563{
6564 HINSTANCE hKernel32;
6565 /* only recheck */
6566 if (has_CreateSymbolicLinkW)
6567 return has_CreateSymbolicLinkW;
Martin v. Löwis50590f12012-01-14 17:54:09 +01006568 hKernel32 = GetModuleHandleW(L"KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00006569 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
6570 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00006571 if (Py_CreateSymbolicLinkW)
6572 has_CreateSymbolicLinkW = 1;
6573 return has_CreateSymbolicLinkW;
6574}
6575
6576PyDoc_STRVAR(win_symlink__doc__,
6577"symlink(src, dst, target_is_directory=False)\n\n\
6578Create a symbolic link pointing to src named dst.\n\
6579target_is_directory is required if the target is to be interpreted as\n\
6580a directory.\n\
6581This function requires Windows 6.0 or greater, and raises a\n\
6582NotImplementedError otherwise.");
6583
6584static PyObject *
6585win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
6586{
6587 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006588 PyObject *osrc, *odest;
6589 PyObject *usrc = NULL, *udest = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006590 wchar_t *wsrc, *wdest;
Brian Curtind40e6f72010-07-08 21:39:08 +00006591 int target_is_directory = 0;
6592 DWORD res;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006593
Brian Curtind40e6f72010-07-08 21:39:08 +00006594 if (!check_CreateSymbolicLinkW())
6595 {
6596 /* raise NotImplementedError */
6597 return PyErr_Format(PyExc_NotImplementedError,
6598 "CreateSymbolicLinkW not found");
6599 }
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006600 if (!PyArg_ParseTupleAndKeywords(
6601 args, kwargs, "OO|i:symlink", kwlist,
6602 &osrc, &odest, &target_is_directory))
Brian Curtind40e6f72010-07-08 21:39:08 +00006603 return NULL;
Brian Curtin3b4499c2010-12-28 14:31:47 +00006604
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006605 usrc = win32_decode_filename(osrc);
6606 if (!usrc)
6607 return NULL;
6608 udest = win32_decode_filename(odest);
6609 if (!udest)
6610 goto error;
6611
Brian Curtin3b4499c2010-12-28 14:31:47 +00006612 if (win32_can_symlink == 0)
6613 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
6614
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006615 wsrc = PyUnicode_AsUnicode(usrc);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006616 if (wsrc == NULL)
6617 goto error;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006618 wdest = PyUnicode_AsUnicode(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006619 if (wsrc == NULL)
6620 goto error;
6621
Brian Curtind40e6f72010-07-08 21:39:08 +00006622 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006623 res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Brian Curtind40e6f72010-07-08 21:39:08 +00006624 Py_END_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006625
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006626 Py_DECREF(usrc);
6627 Py_DECREF(udest);
Brian Curtind40e6f72010-07-08 21:39:08 +00006628 if (!res)
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006629 return win32_error_object("symlink", osrc);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006630
Brian Curtind40e6f72010-07-08 21:39:08 +00006631 Py_INCREF(Py_None);
6632 return Py_None;
Victor Stinnereb5657a2011-09-30 01:44:27 +02006633
6634error:
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006635 Py_XDECREF(usrc);
6636 Py_XDECREF(udest);
Victor Stinnereb5657a2011-09-30 01:44:27 +02006637 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00006638}
Brian Curtin52173d42010-12-02 18:29:18 +00006639#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006640
6641#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006642#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6643static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006644system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006645{
6646 ULONG value = 0;
6647
6648 Py_BEGIN_ALLOW_THREADS
6649 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6650 Py_END_ALLOW_THREADS
6651
6652 return value;
6653}
6654
6655static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006656posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006657{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006658 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 return Py_BuildValue("ddddd",
6660 (double)0 /* t.tms_utime / HZ */,
6661 (double)0 /* t.tms_stime / HZ */,
6662 (double)0 /* t.tms_cutime / HZ */,
6663 (double)0 /* t.tms_cstime / HZ */,
6664 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006665}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006666#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00006667#define NEED_TICKS_PER_SECOND
6668static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006669static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006670posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006671{
Victor Stinner8c62be82010-05-06 00:08:46 +00006672 struct tms t;
6673 clock_t c;
6674 errno = 0;
6675 c = times(&t);
6676 if (c == (clock_t) -1)
6677 return posix_error();
6678 return Py_BuildValue("ddddd",
6679 (double)t.tms_utime / ticks_per_second,
6680 (double)t.tms_stime / ticks_per_second,
6681 (double)t.tms_cutime / ticks_per_second,
6682 (double)t.tms_cstime / ticks_per_second,
6683 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006684}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006685#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006686#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006687
6688
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006689#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006690#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006691static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006692posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006693{
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 FILETIME create, exit, kernel, user;
6695 HANDLE hProc;
6696 hProc = GetCurrentProcess();
6697 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6698 /* The fields of a FILETIME structure are the hi and lo part
6699 of a 64-bit value expressed in 100 nanosecond units.
6700 1e7 is one second in such units; 1e-7 the inverse.
6701 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6702 */
6703 return Py_BuildValue(
6704 "ddddd",
6705 (double)(user.dwHighDateTime*429.4967296 +
6706 user.dwLowDateTime*1e-7),
6707 (double)(kernel.dwHighDateTime*429.4967296 +
6708 kernel.dwLowDateTime*1e-7),
6709 (double)0,
6710 (double)0,
6711 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006712}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006713#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006714
6715#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006716PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006717"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006718Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006719#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006720
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006721
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006722#ifdef HAVE_GETSID
6723PyDoc_STRVAR(posix_getsid__doc__,
6724"getsid(pid) -> sid\n\n\
6725Call the system call getsid().");
6726
6727static PyObject *
6728posix_getsid(PyObject *self, PyObject *args)
6729{
Victor Stinner8c62be82010-05-06 00:08:46 +00006730 pid_t pid;
6731 int sid;
6732 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
6733 return NULL;
6734 sid = getsid(pid);
6735 if (sid < 0)
6736 return posix_error();
6737 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006738}
6739#endif /* HAVE_GETSID */
6740
6741
Guido van Rossumb6775db1994-08-01 11:34:53 +00006742#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006743PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006744"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006745Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006746
Barry Warsaw53699e91996-12-10 23:23:01 +00006747static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006748posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006749{
Victor Stinner8c62be82010-05-06 00:08:46 +00006750 if (setsid() < 0)
6751 return posix_error();
6752 Py_INCREF(Py_None);
6753 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006754}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006755#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006756
Guido van Rossumb6775db1994-08-01 11:34:53 +00006757#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006758PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006759"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006760Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006761
Barry Warsaw53699e91996-12-10 23:23:01 +00006762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006763posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006764{
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 pid_t pid;
6766 int pgrp;
6767 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
6768 return NULL;
6769 if (setpgid(pid, pgrp) < 0)
6770 return posix_error();
6771 Py_INCREF(Py_None);
6772 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006773}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006774#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006775
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006776
Guido van Rossumb6775db1994-08-01 11:34:53 +00006777#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006778PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006779"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006780Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006781
Barry Warsaw53699e91996-12-10 23:23:01 +00006782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006783posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006784{
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 int fd;
6786 pid_t pgid;
6787 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6788 return NULL;
6789 pgid = tcgetpgrp(fd);
6790 if (pgid < 0)
6791 return posix_error();
6792 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006793}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006794#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006796
Guido van Rossumb6775db1994-08-01 11:34:53 +00006797#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006798PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006799"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006800Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006801
Barry Warsaw53699e91996-12-10 23:23:01 +00006802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006803posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006804{
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 int fd;
6806 pid_t pgid;
6807 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
6808 return NULL;
6809 if (tcsetpgrp(fd, pgid) < 0)
6810 return posix_error();
6811 Py_INCREF(Py_None);
6812 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006813}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006814#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006815
Guido van Rossum687dd131993-05-17 08:34:16 +00006816/* Functions acting on file descriptors */
6817
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006818PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006819"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006820Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006821
Barry Warsaw53699e91996-12-10 23:23:01 +00006822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006823posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006824{
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 PyObject *ofile;
6826 char *file;
6827 int flag;
6828 int mode = 0777;
6829 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006830
6831#ifdef MS_WINDOWS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006832 PyObject *po;
Victor Stinner26de69d2011-06-17 15:15:38 +02006833 if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02006834 wchar_t *wpath = PyUnicode_AsUnicode(po);
6835 if (wpath == NULL)
6836 return NULL;
6837
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02006839 fd = _wopen(wpath, flag, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 Py_END_ALLOW_THREADS
6841 if (fd < 0)
6842 return posix_error();
6843 return PyLong_FromLong((long)fd);
6844 }
6845 /* Drop the argument parsing error as narrow strings
6846 are also valid. */
6847 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006848#endif
6849
Victor Stinner26de69d2011-06-17 15:15:38 +02006850 if (!PyArg_ParseTuple(args, "O&i|i:open",
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 PyUnicode_FSConverter, &ofile,
6852 &flag, &mode))
6853 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01006854#ifdef MS_WINDOWS
6855 if (win32_warn_bytes_api()) {
6856 Py_DECREF(ofile);
6857 return NULL;
6858 }
6859#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 file = PyBytes_AsString(ofile);
6861 Py_BEGIN_ALLOW_THREADS
6862 fd = open(file, flag, mode);
6863 Py_END_ALLOW_THREADS
6864 if (fd < 0)
6865 return posix_error_with_allocated_filename(ofile);
6866 Py_DECREF(ofile);
6867 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006868}
6869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006870
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006871PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006872"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006873Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006874
Barry Warsaw53699e91996-12-10 23:23:01 +00006875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006876posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006877{
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 int fd, res;
6879 if (!PyArg_ParseTuple(args, "i:close", &fd))
6880 return NULL;
6881 if (!_PyVerify_fd(fd))
6882 return posix_error();
6883 Py_BEGIN_ALLOW_THREADS
6884 res = close(fd);
6885 Py_END_ALLOW_THREADS
6886 if (res < 0)
6887 return posix_error();
6888 Py_INCREF(Py_None);
6889 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006890}
6891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006892
Victor Stinner8c62be82010-05-06 00:08:46 +00006893PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00006894"closerange(fd_low, fd_high)\n\n\
6895Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6896
6897static PyObject *
6898posix_closerange(PyObject *self, PyObject *args)
6899{
Victor Stinner8c62be82010-05-06 00:08:46 +00006900 int fd_from, fd_to, i;
6901 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6902 return NULL;
6903 Py_BEGIN_ALLOW_THREADS
6904 for (i = fd_from; i < fd_to; i++)
6905 if (_PyVerify_fd(i))
6906 close(i);
6907 Py_END_ALLOW_THREADS
6908 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00006909}
6910
6911
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006912PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006913"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006914Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006915
Barry Warsaw53699e91996-12-10 23:23:01 +00006916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006917posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006918{
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 int fd;
6920 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6921 return NULL;
6922 if (!_PyVerify_fd(fd))
6923 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006924 fd = dup(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 if (fd < 0)
6926 return posix_error();
6927 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006928}
6929
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006930
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006931PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006932"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006933Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006934
Barry Warsaw53699e91996-12-10 23:23:01 +00006935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006936posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006937{
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 int fd, fd2, res;
6939 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6940 return NULL;
6941 if (!_PyVerify_fd_dup2(fd, fd2))
6942 return posix_error();
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 res = dup2(fd, fd2);
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 if (res < 0)
6945 return posix_error();
6946 Py_INCREF(Py_None);
6947 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006948}
6949
Ross Lagerwall7807c352011-03-17 20:20:30 +02006950#ifdef HAVE_LOCKF
6951PyDoc_STRVAR(posix_lockf__doc__,
6952"lockf(fd, cmd, len)\n\n\
6953Apply, test or remove a POSIX lock on an open file descriptor.\n\n\
6954fd is an open file descriptor.\n\
6955cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\
6956F_TEST.\n\
6957len specifies the section of the file to lock.");
6958
6959static PyObject *
6960posix_lockf(PyObject *self, PyObject *args)
6961{
6962 int fd, cmd, res;
6963 off_t len;
6964 if (!PyArg_ParseTuple(args, "iiO&:lockf",
6965 &fd, &cmd, _parse_off_t, &len))
6966 return NULL;
6967
6968 Py_BEGIN_ALLOW_THREADS
6969 res = lockf(fd, cmd, len);
6970 Py_END_ALLOW_THREADS
6971
6972 if (res < 0)
6973 return posix_error();
6974
6975 Py_RETURN_NONE;
6976}
6977#endif
6978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006979
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006980PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006981"lseek(fd, pos, how) -> newpos\n\n\
Victor Stinnere83f8992011-12-17 23:15:09 +01006982Set the current position of a file descriptor.\n\
6983Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006984
Barry Warsaw53699e91996-12-10 23:23:01 +00006985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006986posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006987{
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006989#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00006990 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006991#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006993#endif
Ross Lagerwall8e749672011-03-17 21:54:07 +02006994 PyObject *posobj;
6995 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Victor Stinner8c62be82010-05-06 00:08:46 +00006996 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006997#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6999 switch (how) {
7000 case 0: how = SEEK_SET; break;
7001 case 1: how = SEEK_CUR; break;
7002 case 2: how = SEEK_END; break;
7003 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007004#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007005
Ross Lagerwall8e749672011-03-17 21:54:07 +02007006#if !defined(HAVE_LARGEFILE_SUPPORT)
7007 pos = PyLong_AsLong(posobj);
7008#else
7009 pos = PyLong_AsLongLong(posobj);
7010#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 if (PyErr_Occurred())
7012 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007013
Victor Stinner8c62be82010-05-06 00:08:46 +00007014 if (!_PyVerify_fd(fd))
7015 return posix_error();
7016 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007017#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007019#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00007021#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 Py_END_ALLOW_THREADS
7023 if (res < 0)
7024 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007025
7026#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007028#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007029 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007030#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007031}
7032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007033
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007034PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007035"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007036Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007037
Barry Warsaw53699e91996-12-10 23:23:01 +00007038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007039posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00007040{
Victor Stinner8c62be82010-05-06 00:08:46 +00007041 int fd, size;
7042 Py_ssize_t n;
7043 PyObject *buffer;
7044 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
7045 return NULL;
7046 if (size < 0) {
7047 errno = EINVAL;
7048 return posix_error();
7049 }
7050 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7051 if (buffer == NULL)
7052 return NULL;
Stefan Krah99439262010-11-26 12:58:05 +00007053 if (!_PyVerify_fd(fd)) {
7054 Py_DECREF(buffer);
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 return posix_error();
Stefan Krah99439262010-11-26 12:58:05 +00007056 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 Py_BEGIN_ALLOW_THREADS
7058 n = read(fd, PyBytes_AS_STRING(buffer), size);
7059 Py_END_ALLOW_THREADS
7060 if (n < 0) {
7061 Py_DECREF(buffer);
7062 return posix_error();
7063 }
7064 if (n != size)
7065 _PyBytes_Resize(&buffer, n);
7066 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007067}
7068
Ross Lagerwall7807c352011-03-17 20:20:30 +02007069#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7070 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007071static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007072iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7073{
7074 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007075 Py_ssize_t blen, total = 0;
7076
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007077 *iov = PyMem_New(struct iovec, cnt);
7078 if (*iov == NULL) {
7079 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007080 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007081 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007082
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007083 *buf = PyMem_New(Py_buffer, cnt);
7084 if (*buf == NULL) {
7085 PyMem_Del(*iov);
7086 PyErr_NoMemory();
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007087 return total;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007088 }
7089
7090 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007091 PyObject *item = PySequence_GetItem(seq, i);
7092 if (item == NULL)
7093 goto fail;
7094 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7095 Py_DECREF(item);
7096 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007097 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007098 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007099 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007100 blen = (*buf)[i].len;
7101 (*iov)[i].iov_len = blen;
7102 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007103 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007104 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007105
7106fail:
7107 PyMem_Del(*iov);
7108 for (j = 0; j < i; j++) {
7109 PyBuffer_Release(&(*buf)[j]);
7110 }
7111 PyMem_Del(*buf);
7112 return 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007113}
7114
7115static void
7116iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7117{
7118 int i;
7119 PyMem_Del(iov);
7120 for (i = 0; i < cnt; i++) {
7121 PyBuffer_Release(&buf[i]);
7122 }
7123 PyMem_Del(buf);
7124}
7125#endif
7126
Ross Lagerwall7807c352011-03-17 20:20:30 +02007127#ifdef HAVE_READV
7128PyDoc_STRVAR(posix_readv__doc__,
7129"readv(fd, buffers) -> bytesread\n\n\
7130Read from a file descriptor into a number of writable buffers. buffers\n\
7131is an arbitrary sequence of writable buffers.\n\
7132Returns the total number of bytes read.");
7133
7134static PyObject *
7135posix_readv(PyObject *self, PyObject *args)
7136{
7137 int fd, cnt;
7138 Py_ssize_t n;
7139 PyObject *seq;
7140 struct iovec *iov;
7141 Py_buffer *buf;
7142
7143 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq))
7144 return NULL;
7145 if (!PySequence_Check(seq)) {
7146 PyErr_SetString(PyExc_TypeError,
7147 "readv() arg 2 must be a sequence");
7148 return NULL;
7149 }
7150 cnt = PySequence_Size(seq);
7151
7152 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE))
7153 return NULL;
7154
7155 Py_BEGIN_ALLOW_THREADS
7156 n = readv(fd, iov, cnt);
7157 Py_END_ALLOW_THREADS
7158
7159 iov_cleanup(iov, buf, cnt);
7160 return PyLong_FromSsize_t(n);
7161}
7162#endif
7163
7164#ifdef HAVE_PREAD
7165PyDoc_STRVAR(posix_pread__doc__,
7166"pread(fd, buffersize, offset) -> string\n\n\
7167Read from a file descriptor, fd, at a position of offset. It will read up\n\
7168to buffersize number of bytes. The file offset remains unchanged.");
7169
7170static PyObject *
7171posix_pread(PyObject *self, PyObject *args)
7172{
7173 int fd, size;
7174 off_t offset;
7175 Py_ssize_t n;
7176 PyObject *buffer;
7177 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset))
7178 return NULL;
7179
7180 if (size < 0) {
7181 errno = EINVAL;
7182 return posix_error();
7183 }
7184 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
7185 if (buffer == NULL)
7186 return NULL;
7187 if (!_PyVerify_fd(fd)) {
7188 Py_DECREF(buffer);
7189 return posix_error();
7190 }
7191 Py_BEGIN_ALLOW_THREADS
7192 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset);
7193 Py_END_ALLOW_THREADS
7194 if (n < 0) {
7195 Py_DECREF(buffer);
7196 return posix_error();
7197 }
7198 if (n != size)
7199 _PyBytes_Resize(&buffer, n);
7200 return buffer;
7201}
7202#endif
7203
7204PyDoc_STRVAR(posix_write__doc__,
7205"write(fd, string) -> byteswritten\n\n\
7206Write a string to a file descriptor.");
7207
7208static PyObject *
7209posix_write(PyObject *self, PyObject *args)
7210{
7211 Py_buffer pbuf;
7212 int fd;
7213 Py_ssize_t size, len;
7214
7215 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
7216 return NULL;
7217 if (!_PyVerify_fd(fd)) {
7218 PyBuffer_Release(&pbuf);
7219 return posix_error();
7220 }
7221 len = pbuf.len;
7222 Py_BEGIN_ALLOW_THREADS
7223#if defined(MS_WIN64) || defined(MS_WINDOWS)
7224 if (len > INT_MAX)
7225 len = INT_MAX;
7226 size = write(fd, pbuf.buf, (int)len);
7227#else
7228 size = write(fd, pbuf.buf, len);
7229#endif
7230 Py_END_ALLOW_THREADS
7231 PyBuffer_Release(&pbuf);
7232 if (size < 0)
7233 return posix_error();
7234 return PyLong_FromSsize_t(size);
7235}
7236
7237#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007238PyDoc_STRVAR(posix_sendfile__doc__,
7239"sendfile(out, in, offset, nbytes) -> byteswritten\n\
7240sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
7241 -> byteswritten\n\
7242Copy nbytes bytes from file descriptor in to file descriptor out.");
7243
7244static PyObject *
7245posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7246{
7247 int in, out;
7248 Py_ssize_t ret;
7249 off_t offset;
7250
7251#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7252#ifndef __APPLE__
7253 Py_ssize_t len;
7254#endif
7255 PyObject *headers = NULL, *trailers = NULL;
7256 Py_buffer *hbuf, *tbuf;
7257 off_t sbytes;
7258 struct sf_hdtr sf;
7259 int flags = 0;
7260 sf.headers = NULL;
7261 sf.trailers = NULL;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00007262 static char *keywords[] = {"out", "in",
7263 "offset", "count",
7264 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007265
7266#ifdef __APPLE__
7267 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007268 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007269#else
7270 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Georg Brandla391b112011-02-25 15:23:18 +00007271 keywords, &out, &in, _parse_off_t, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007272#endif
7273 &headers, &trailers, &flags))
7274 return NULL;
7275 if (headers != NULL) {
7276 if (!PySequence_Check(headers)) {
7277 PyErr_SetString(PyExc_TypeError,
7278 "sendfile() headers must be a sequence or None");
7279 return NULL;
7280 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007281 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007282 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007283 if (sf.hdr_cnt > 0 &&
7284 !(i = iov_setup(&(sf.headers), &hbuf,
7285 headers, sf.hdr_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007286 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007287#ifdef __APPLE__
7288 sbytes += i;
7289#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007290 }
7291 }
7292 if (trailers != NULL) {
7293 if (!PySequence_Check(trailers)) {
7294 PyErr_SetString(PyExc_TypeError,
7295 "sendfile() trailers must be a sequence or None");
7296 return NULL;
7297 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007298 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007299 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007300 if (sf.trl_cnt > 0 &&
7301 !(i = iov_setup(&(sf.trailers), &tbuf,
7302 trailers, sf.trl_cnt, PyBUF_SIMPLE)))
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007303 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007304#ifdef __APPLE__
7305 sbytes += i;
7306#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007307 }
7308 }
7309
7310 Py_BEGIN_ALLOW_THREADS
7311#ifdef __APPLE__
7312 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
7313#else
7314 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
7315#endif
7316 Py_END_ALLOW_THREADS
7317
7318 if (sf.headers != NULL)
7319 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
7320 if (sf.trailers != NULL)
7321 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
7322
7323 if (ret < 0) {
7324 if ((errno == EAGAIN) || (errno == EBUSY)) {
7325 if (sbytes != 0) {
7326 // some data has been sent
7327 goto done;
7328 }
7329 else {
7330 // no data has been sent; upper application is supposed
7331 // to retry on EAGAIN or EBUSY
7332 return posix_error();
7333 }
7334 }
7335 return posix_error();
7336 }
7337 goto done;
7338
7339done:
7340 #if !defined(HAVE_LARGEFILE_SUPPORT)
7341 return Py_BuildValue("l", sbytes);
7342 #else
7343 return Py_BuildValue("L", sbytes);
7344 #endif
7345
7346#else
7347 Py_ssize_t count;
7348 PyObject *offobj;
7349 static char *keywords[] = {"out", "in",
7350 "offset", "count", NULL};
7351 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
7352 keywords, &out, &in, &offobj, &count))
7353 return NULL;
7354#ifdef linux
7355 if (offobj == Py_None) {
7356 Py_BEGIN_ALLOW_THREADS
7357 ret = sendfile(out, in, NULL, count);
7358 Py_END_ALLOW_THREADS
7359 if (ret < 0)
7360 return posix_error();
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02007361 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007362 }
7363#endif
Antoine Pitroudcc20b82011-02-26 13:38:35 +00007364 if (!_parse_off_t(offobj, &offset))
7365 return NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007366 Py_BEGIN_ALLOW_THREADS
7367 ret = sendfile(out, in, &offset, count);
7368 Py_END_ALLOW_THREADS
7369 if (ret < 0)
7370 return posix_error();
7371 return Py_BuildValue("n", ret);
7372#endif
7373}
7374#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007375
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007376PyDoc_STRVAR(posix_fstat__doc__,
Victor Stinnerccd57152012-02-08 14:31:50 +01007377"fstat(fd, timestamp=None) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007378Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007379
Barry Warsaw53699e91996-12-10 23:23:01 +00007380static PyObject *
Victor Stinnerccd57152012-02-08 14:31:50 +01007381posix_fstat(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007382{
Victor Stinnerccd57152012-02-08 14:31:50 +01007383 static char *kwlist[] = {"fd", "timestamp", NULL};
Victor Stinner8c62be82010-05-06 00:08:46 +00007384 int fd;
7385 STRUCT_STAT st;
7386 int res;
Victor Stinnerccd57152012-02-08 14:31:50 +01007387 PyObject *timestamp = NULL;
7388 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|O:fstat", kwlist,
7389 &fd, &timestamp))
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007391#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007392 /* on OpenVMS we must ensure that all bytes are written to the file */
7393 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00007394#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007395 if (!_PyVerify_fd(fd))
7396 return posix_error();
7397 Py_BEGIN_ALLOW_THREADS
7398 res = FSTAT(fd, &st);
7399 Py_END_ALLOW_THREADS
7400 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00007401#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007402 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00007403#else
Victor Stinner8c62be82010-05-06 00:08:46 +00007404 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00007405#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007406 }
Tim Peters5aa91602002-01-30 05:46:57 +00007407
Victor Stinnerccd57152012-02-08 14:31:50 +01007408 return _pystat_fromstructstat(&st, timestamp);
Guido van Rossum687dd131993-05-17 08:34:16 +00007409}
7410
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007411PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007412"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007413Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007414connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00007415
7416static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00007417posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00007418{
Victor Stinner8c62be82010-05-06 00:08:46 +00007419 int fd;
7420 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
7421 return NULL;
7422 if (!_PyVerify_fd(fd))
7423 return PyBool_FromLong(0);
7424 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00007425}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007426
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007427#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007428PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007429"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007430Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007431
Barry Warsaw53699e91996-12-10 23:23:01 +00007432static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007433posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00007434{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007435#if defined(PYOS_OS2)
7436 HFILE read, write;
7437 APIRET rc;
7438
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007439 rc = DosCreatePipe( &read, &write, 4096);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007440 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007441 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007442
7443 return Py_BuildValue("(ii)", read, write);
7444#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007445#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00007446 int fds[2];
7447 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007448 res = pipe(fds);
Victor Stinner8c62be82010-05-06 00:08:46 +00007449 if (res != 0)
7450 return posix_error();
7451 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007452#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007453 HANDLE read, write;
7454 int read_fd, write_fd;
7455 BOOL ok;
Victor Stinner8c62be82010-05-06 00:08:46 +00007456 ok = CreatePipe(&read, &write, NULL, 0);
Victor Stinner8c62be82010-05-06 00:08:46 +00007457 if (!ok)
7458 return win32_error("CreatePipe", NULL);
7459 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7460 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7461 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007462#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007463#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007464}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007465#endif /* HAVE_PIPE */
7466
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007467#ifdef HAVE_PIPE2
7468PyDoc_STRVAR(posix_pipe2__doc__,
Charles-François Natali368f34b2011-06-06 19:49:47 +02007469"pipe2(flags) -> (read_end, write_end)\n\n\
7470Create a pipe with flags set atomically.\n\
7471flags can be constructed by ORing together one or more of these values:\n\
7472O_NONBLOCK, O_CLOEXEC.\n\
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007473");
7474
7475static PyObject *
Charles-François Natali368f34b2011-06-06 19:49:47 +02007476posix_pipe2(PyObject *self, PyObject *arg)
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007477{
Charles-François Natali368f34b2011-06-06 19:49:47 +02007478 int flags;
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007479 int fds[2];
7480 int res;
7481
Charles-François Natali368f34b2011-06-06 19:49:47 +02007482 flags = PyLong_AsLong(arg);
7483 if (flags == -1 && PyErr_Occurred())
Charles-François Natalidaafdd52011-05-29 20:07:40 +02007484 return NULL;
7485
7486 res = pipe2(fds, flags);
7487 if (res != 0)
7488 return posix_error();
7489 return Py_BuildValue("(ii)", fds[0], fds[1]);
7490}
7491#endif /* HAVE_PIPE2 */
7492
Ross Lagerwall7807c352011-03-17 20:20:30 +02007493#ifdef HAVE_WRITEV
7494PyDoc_STRVAR(posix_writev__doc__,
7495"writev(fd, buffers) -> byteswritten\n\n\
7496Write the contents of buffers to a file descriptor, where buffers is an\n\
7497arbitrary sequence of buffers.\n\
7498Returns the total bytes written.");
7499
7500static PyObject *
7501posix_writev(PyObject *self, PyObject *args)
7502{
7503 int fd, cnt;
7504 Py_ssize_t res;
7505 PyObject *seq;
7506 struct iovec *iov;
7507 Py_buffer *buf;
7508 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq))
7509 return NULL;
7510 if (!PySequence_Check(seq)) {
7511 PyErr_SetString(PyExc_TypeError,
7512 "writev() arg 2 must be a sequence");
7513 return NULL;
7514 }
7515 cnt = PySequence_Size(seq);
7516
7517 if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) {
7518 return NULL;
7519 }
7520
7521 Py_BEGIN_ALLOW_THREADS
7522 res = writev(fd, iov, cnt);
7523 Py_END_ALLOW_THREADS
7524
7525 iov_cleanup(iov, buf, cnt);
7526 return PyLong_FromSsize_t(res);
7527}
7528#endif
7529
7530#ifdef HAVE_PWRITE
7531PyDoc_STRVAR(posix_pwrite__doc__,
7532"pwrite(fd, string, offset) -> byteswritten\n\n\
7533Write string to a file descriptor, fd, from offset, leaving the file\n\
7534offset unchanged.");
7535
7536static PyObject *
7537posix_pwrite(PyObject *self, PyObject *args)
7538{
7539 Py_buffer pbuf;
7540 int fd;
7541 off_t offset;
7542 Py_ssize_t size;
7543
7544 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset))
7545 return NULL;
7546
7547 if (!_PyVerify_fd(fd)) {
7548 PyBuffer_Release(&pbuf);
7549 return posix_error();
7550 }
7551 Py_BEGIN_ALLOW_THREADS
7552 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset);
7553 Py_END_ALLOW_THREADS
7554 PyBuffer_Release(&pbuf);
7555 if (size < 0)
7556 return posix_error();
7557 return PyLong_FromSsize_t(size);
7558}
7559#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007560
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007561#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007562PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007563"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007564Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007565
Barry Warsaw53699e91996-12-10 23:23:01 +00007566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007567posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007568{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007569 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007570 char *filename;
7571 int mode = 0666;
7572 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007573 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
7574 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00007575 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007576 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 Py_BEGIN_ALLOW_THREADS
7578 res = mkfifo(filename, mode);
7579 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007580 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007581 if (res < 0)
7582 return posix_error();
7583 Py_INCREF(Py_None);
7584 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007585}
7586#endif
7587
7588
Neal Norwitz11690112002-07-30 01:08:28 +00007589#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007590PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007591"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007592Create a filesystem node (file, device special file or named pipe)\n\
7593named filename. mode specifies both the permissions to use and the\n\
7594type of node to be created, being combined (bitwise OR) with one of\n\
7595S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007596device defines the newly created device special file (probably using\n\
7597os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007598
7599
7600static PyObject *
7601posix_mknod(PyObject *self, PyObject *args)
7602{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007603 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 char *filename;
7605 int mode = 0600;
7606 int device = 0;
7607 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007608 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
7609 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007611 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007612 Py_BEGIN_ALLOW_THREADS
7613 res = mknod(filename, mode, device);
7614 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00007615 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 if (res < 0)
7617 return posix_error();
7618 Py_INCREF(Py_None);
7619 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007620}
7621#endif
7622
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007623#ifdef HAVE_DEVICE_MACROS
7624PyDoc_STRVAR(posix_major__doc__,
7625"major(device) -> major number\n\
7626Extracts a device major number from a raw device number.");
7627
7628static PyObject *
7629posix_major(PyObject *self, PyObject *args)
7630{
Victor Stinner8c62be82010-05-06 00:08:46 +00007631 int device;
7632 if (!PyArg_ParseTuple(args, "i:major", &device))
7633 return NULL;
7634 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007635}
7636
7637PyDoc_STRVAR(posix_minor__doc__,
7638"minor(device) -> minor number\n\
7639Extracts a device minor number from a raw device number.");
7640
7641static PyObject *
7642posix_minor(PyObject *self, PyObject *args)
7643{
Victor Stinner8c62be82010-05-06 00:08:46 +00007644 int device;
7645 if (!PyArg_ParseTuple(args, "i:minor", &device))
7646 return NULL;
7647 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007648}
7649
7650PyDoc_STRVAR(posix_makedev__doc__,
7651"makedev(major, minor) -> device number\n\
7652Composes a raw device number from the major and minor device numbers.");
7653
7654static PyObject *
7655posix_makedev(PyObject *self, PyObject *args)
7656{
Victor Stinner8c62be82010-05-06 00:08:46 +00007657 int major, minor;
7658 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7659 return NULL;
7660 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007661}
7662#endif /* device macros */
7663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007664
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007665#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007666PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007667"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007668Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007669
Barry Warsaw53699e91996-12-10 23:23:01 +00007670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007671posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007672{
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 int fd;
7674 off_t length;
7675 int res;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007676
Ross Lagerwall7807c352011-03-17 20:20:30 +02007677 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length))
Victor Stinner8c62be82010-05-06 00:08:46 +00007678 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007679
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 Py_BEGIN_ALLOW_THREADS
7681 res = ftruncate(fd, length);
7682 Py_END_ALLOW_THREADS
7683 if (res < 0)
7684 return posix_error();
7685 Py_INCREF(Py_None);
7686 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007687}
7688#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007689
Ross Lagerwall7807c352011-03-17 20:20:30 +02007690#ifdef HAVE_TRUNCATE
7691PyDoc_STRVAR(posix_truncate__doc__,
7692"truncate(path, length)\n\n\
7693Truncate the file given by path to length bytes.");
7694
7695static PyObject *
7696posix_truncate(PyObject *self, PyObject *args)
7697{
7698 PyObject *opath;
7699 const char *path;
7700 off_t length;
7701 int res;
7702
7703 if (!PyArg_ParseTuple(args, "O&O&:truncate",
7704 PyUnicode_FSConverter, &opath, _parse_off_t, &length))
7705 return NULL;
7706 path = PyBytes_AsString(opath);
7707
7708 Py_BEGIN_ALLOW_THREADS
7709 res = truncate(path, length);
7710 Py_END_ALLOW_THREADS
7711 Py_DECREF(opath);
7712 if (res < 0)
7713 return posix_error();
7714 Py_RETURN_NONE;
7715}
7716#endif
7717
7718#ifdef HAVE_POSIX_FALLOCATE
7719PyDoc_STRVAR(posix_posix_fallocate__doc__,
7720"posix_fallocate(fd, offset, len)\n\n\
7721Ensures that enough disk space is allocated for the file specified by fd\n\
7722starting from offset and continuing for len bytes.");
7723
7724static PyObject *
7725posix_posix_fallocate(PyObject *self, PyObject *args)
7726{
7727 off_t len, offset;
7728 int res, fd;
7729
7730 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate",
7731 &fd, _parse_off_t, &offset, _parse_off_t, &len))
7732 return NULL;
7733
7734 Py_BEGIN_ALLOW_THREADS
7735 res = posix_fallocate(fd, offset, len);
7736 Py_END_ALLOW_THREADS
7737 if (res != 0) {
7738 errno = res;
7739 return posix_error();
7740 }
7741 Py_RETURN_NONE;
7742}
7743#endif
7744
7745#ifdef HAVE_POSIX_FADVISE
7746PyDoc_STRVAR(posix_posix_fadvise__doc__,
7747"posix_fadvise(fd, offset, len, advice)\n\n\
7748Announces an intention to access data in a specific pattern thus allowing\n\
7749the kernel to make optimizations.\n\
7750The advice applies to the region of the file specified by fd starting at\n\
7751offset and continuing for len bytes.\n\
7752advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\
7753POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\
7754POSIX_FADV_DONTNEED.");
7755
7756static PyObject *
7757posix_posix_fadvise(PyObject *self, PyObject *args)
7758{
7759 off_t len, offset;
7760 int res, fd, advice;
7761
7762 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise",
7763 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice))
7764 return NULL;
7765
7766 Py_BEGIN_ALLOW_THREADS
7767 res = posix_fadvise(fd, offset, len, advice);
7768 Py_END_ALLOW_THREADS
7769 if (res != 0) {
7770 errno = res;
7771 return posix_error();
7772 }
7773 Py_RETURN_NONE;
7774}
7775#endif
7776
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007777#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007778PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007779"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007780Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007781
Fred Drake762e2061999-08-26 17:23:54 +00007782/* Save putenv() parameters as values here, so we can collect them when they
7783 * get re-set with another call for the same key. */
7784static PyObject *posix_putenv_garbage;
7785
Tim Peters5aa91602002-01-30 05:46:57 +00007786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007787posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007788{
Victor Stinner84ae1182010-05-06 22:05:07 +00007789 PyObject *newstr = NULL;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007790#ifdef MS_WINDOWS
Victor Stinner65170952011-11-22 22:16:17 +01007791 PyObject *os1, *os2;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007792 wchar_t *newenv;
Victor Stinner65170952011-11-22 22:16:17 +01007793
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 if (!PyArg_ParseTuple(args,
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007795 "UU:putenv",
Victor Stinner65170952011-11-22 22:16:17 +01007796 &os1, &os2))
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007798
Victor Stinner65170952011-11-22 22:16:17 +01007799 newstr = PyUnicode_FromFormat("%U=%U", os1, os2);
Victor Stinner84ae1182010-05-06 22:05:07 +00007800 if (newstr == NULL) {
7801 PyErr_NoMemory();
7802 goto error;
7803 }
Victor Stinner65170952011-11-22 22:16:17 +01007804 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) {
7805 PyErr_Format(PyExc_ValueError,
7806 "the environment variable is longer than %u characters",
7807 _MAX_ENV);
7808 goto error;
7809 }
7810
Victor Stinner8c62be82010-05-06 00:08:46 +00007811 newenv = PyUnicode_AsUnicode(newstr);
Victor Stinnereb5657a2011-09-30 01:44:27 +02007812 if (newenv == NULL)
7813 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 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
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007819 PyObject *os1, *os2;
7820 char *s1, *s2;
7821 char *newenv;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007822
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007823 if (!PyArg_ParseTuple(args,
7824 "O&O&:putenv",
7825 PyUnicode_FSConverter, &os1,
7826 PyUnicode_FSConverter, &os2))
7827 return NULL;
7828 s1 = PyBytes_AsString(os1);
7829 s2 = PyBytes_AsString(os2);
Guido van Rossumad0ee831995-03-01 10:34:45 +00007830
Victor Stinner65170952011-11-22 22:16:17 +01007831 newstr = PyBytes_FromFormat("%s=%s", s1, s2);
Victor Stinner9d3b93b2011-11-22 02:27:30 +01007832 if (newstr == NULL) {
7833 PyErr_NoMemory();
7834 goto error;
7835 }
7836
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 newenv = PyBytes_AS_STRING(newstr);
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00007840 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00007842#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007843
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 /* Install the first arg and newstr in posix_putenv_garbage;
7845 * this will cause previous value to be collected. This has to
7846 * happen after the real putenv() call because the old value
7847 * was still accessible until then. */
Victor Stinner65170952011-11-22 22:16:17 +01007848 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 /* really not much we can do; just leak */
7850 PyErr_Clear();
7851 }
7852 else {
7853 Py_DECREF(newstr);
7854 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007855
Martin v. Löwis011e8422009-05-05 04:43:17 +00007856#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 Py_DECREF(os1);
7858 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00007859#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007860 Py_RETURN_NONE;
7861
7862error:
7863#ifndef MS_WINDOWS
7864 Py_DECREF(os1);
7865 Py_DECREF(os2);
7866#endif
7867 Py_XDECREF(newstr);
7868 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00007869}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007870#endif /* putenv */
7871
Guido van Rossumc524d952001-10-19 01:31:59 +00007872#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007873PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007874"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007875Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007876
7877static PyObject *
7878posix_unsetenv(PyObject *self, PyObject *args)
7879{
Victor Stinner65170952011-11-22 22:16:17 +01007880 PyObject *name;
Victor Stinner984890f2011-11-24 13:53:38 +01007881#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01007882 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01007883#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00007884
7885 if (!PyArg_ParseTuple(args, "O&:unsetenv",
Guido van Rossumc524d952001-10-19 01:31:59 +00007886
Victor Stinner65170952011-11-22 22:16:17 +01007887 PyUnicode_FSConverter, &name))
Guido van Rossumc524d952001-10-19 01:31:59 +00007888 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007889
Victor Stinner984890f2011-11-24 13:53:38 +01007890#ifdef HAVE_BROKEN_UNSETENV
7891 unsetenv(PyBytes_AS_STRING(name));
7892#else
Victor Stinner65170952011-11-22 22:16:17 +01007893 err = unsetenv(PyBytes_AS_STRING(name));
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007894 if (err) {
Benjamin Petersone8eb0e82011-11-22 23:14:47 -06007895 Py_DECREF(name);
Victor Stinner60b385e2011-11-22 22:01:28 +01007896 return posix_error();
Benjamin Peterson4bb867d2011-11-22 23:12:49 -06007897 }
Victor Stinner984890f2011-11-24 13:53:38 +01007898#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007899
Victor Stinner8c62be82010-05-06 00:08:46 +00007900 /* Remove the key from posix_putenv_garbage;
7901 * this will cause it to be collected. This has to
7902 * happen after the real unsetenv() call because the
7903 * old value was still accessible until then.
7904 */
Victor Stinner65170952011-11-22 22:16:17 +01007905 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 /* really not much we can do; just leak */
7907 PyErr_Clear();
7908 }
Victor Stinner65170952011-11-22 22:16:17 +01007909 Py_DECREF(name);
Victor Stinner84ae1182010-05-06 22:05:07 +00007910 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00007911}
7912#endif /* unsetenv */
7913
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007914PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007915"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007916Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007917
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007919posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007920{
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 int code;
7922 char *message;
7923 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7924 return NULL;
7925 message = strerror(code);
7926 if (message == NULL) {
7927 PyErr_SetString(PyExc_ValueError,
7928 "strerror() argument out of range");
7929 return NULL;
7930 }
Victor Stinner1b579672011-12-17 05:47:23 +01007931 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007932}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007933
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007934
Guido van Rossumc9641791998-08-04 15:26:23 +00007935#ifdef HAVE_SYS_WAIT_H
7936
Fred Drake106c1a02002-04-23 15:58:02 +00007937#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007938PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007939"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007940Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007941
7942static PyObject *
7943posix_WCOREDUMP(PyObject *self, PyObject *args)
7944{
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 WAIT_TYPE status;
7946 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007947
Victor Stinner8c62be82010-05-06 00:08:46 +00007948 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7949 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007950
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007952}
7953#endif /* WCOREDUMP */
7954
7955#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007956PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007957"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007958Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007959job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007960
7961static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007962posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007963{
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 WAIT_TYPE status;
7965 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007966
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7968 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007969
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007971}
7972#endif /* WIFCONTINUED */
7973
Guido van Rossumc9641791998-08-04 15:26:23 +00007974#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007975PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007976"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007977Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007978
7979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007980posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007981{
Victor Stinner8c62be82010-05-06 00:08:46 +00007982 WAIT_TYPE status;
7983 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007984
Victor Stinner8c62be82010-05-06 00:08:46 +00007985 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7986 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007987
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007989}
7990#endif /* WIFSTOPPED */
7991
7992#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007993PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007994"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007995Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007996
7997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007998posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007999{
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 WAIT_TYPE status;
8001 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008002
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
8004 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008005
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008007}
8008#endif /* WIFSIGNALED */
8009
8010#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008011PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008012"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008013Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008014system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008015
8016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008017posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008018{
Victor Stinner8c62be82010-05-06 00:08:46 +00008019 WAIT_TYPE status;
8020 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008021
Victor Stinner8c62be82010-05-06 00:08:46 +00008022 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
8023 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008024
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008026}
8027#endif /* WIFEXITED */
8028
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008029#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008030PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008031"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008032Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008033
8034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008035posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008036{
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 WAIT_TYPE status;
8038 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008039
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
8041 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008042
Victor Stinner8c62be82010-05-06 00:08:46 +00008043 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008044}
8045#endif /* WEXITSTATUS */
8046
8047#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008048PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008049"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00008050Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008051value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008052
8053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008054posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008055{
Victor Stinner8c62be82010-05-06 00:08:46 +00008056 WAIT_TYPE status;
8057 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008058
Victor Stinner8c62be82010-05-06 00:08:46 +00008059 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
8060 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008061
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008063}
8064#endif /* WTERMSIG */
8065
8066#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008067PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008068"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008069Return the signal that stopped the process that provided\n\
8070the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00008071
8072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008073posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00008074{
Victor Stinner8c62be82010-05-06 00:08:46 +00008075 WAIT_TYPE status;
8076 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00008077
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
8079 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008080
Victor Stinner8c62be82010-05-06 00:08:46 +00008081 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00008082}
8083#endif /* WSTOPSIG */
8084
8085#endif /* HAVE_SYS_WAIT_H */
8086
8087
Thomas Wouters477c8d52006-05-27 19:21:47 +00008088#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00008089#ifdef _SCO_DS
8090/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
8091 needed definitions in sys/statvfs.h */
8092#define _SVID3
8093#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008094#include <sys/statvfs.h>
8095
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008096static PyObject*
8097_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 PyObject *v = PyStructSequence_New(&StatVFSResultType);
8099 if (v == NULL)
8100 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008101
8102#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00008103 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8104 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8105 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
8106 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
8107 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
8108 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
8109 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
8110 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
8111 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8112 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008113#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008114 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
8115 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
8116 PyStructSequence_SET_ITEM(v, 2,
8117 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
8118 PyStructSequence_SET_ITEM(v, 3,
8119 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
8120 PyStructSequence_SET_ITEM(v, 4,
8121 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
8122 PyStructSequence_SET_ITEM(v, 5,
8123 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
8124 PyStructSequence_SET_ITEM(v, 6,
8125 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
8126 PyStructSequence_SET_ITEM(v, 7,
8127 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
8128 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
8129 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008130#endif
8131
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008133}
8134
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008135PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008136"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008137Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008138
8139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008140posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008141{
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 int fd, res;
8143 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008144
Victor Stinner8c62be82010-05-06 00:08:46 +00008145 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
8146 return NULL;
8147 Py_BEGIN_ALLOW_THREADS
8148 res = fstatvfs(fd, &st);
8149 Py_END_ALLOW_THREADS
8150 if (res != 0)
8151 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008152
Victor Stinner8c62be82010-05-06 00:08:46 +00008153 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008154}
Thomas Wouters477c8d52006-05-27 19:21:47 +00008155#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008156
8157
Thomas Wouters477c8d52006-05-27 19:21:47 +00008158#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008159#include <sys/statvfs.h>
8160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008161PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008162"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008163Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00008164
8165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008166posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00008167{
Victor Stinner6fa67772011-09-20 04:04:33 +02008168 PyObject *path;
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 int res;
8170 struct statvfs st;
Victor Stinner6fa67772011-09-20 04:04:33 +02008171 if (!PyArg_ParseTuple(args, "O&:statvfs", PyUnicode_FSConverter, &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 return NULL;
8173 Py_BEGIN_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008174 res = statvfs(PyBytes_AS_STRING(path), &st);
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 Py_END_ALLOW_THREADS
Victor Stinner6fa67772011-09-20 04:04:33 +02008176 if (res != 0) {
8177 posix_error_with_filename(PyBytes_AS_STRING(path));
8178 Py_DECREF(path);
8179 return NULL;
8180 }
8181 Py_DECREF(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008182
Victor Stinner8c62be82010-05-06 00:08:46 +00008183 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00008184}
8185#endif /* HAVE_STATVFS */
8186
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008187#ifdef MS_WINDOWS
8188PyDoc_STRVAR(win32__getdiskusage__doc__,
8189"_getdiskusage(path) -> (total, free)\n\n\
8190Return disk usage statistics about the given path as (total, free) tuple.");
8191
8192static PyObject *
8193win32__getdiskusage(PyObject *self, PyObject *args)
8194{
8195 BOOL retval;
8196 ULARGE_INTEGER _, total, free;
Victor Stinner6139c1b2011-11-09 22:14:14 +01008197 const wchar_t *path;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008198
Victor Stinner6139c1b2011-11-09 22:14:14 +01008199 if (! PyArg_ParseTuple(args, "u", &path))
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008200 return NULL;
8201
8202 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01008203 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02008204 Py_END_ALLOW_THREADS
8205 if (retval == 0)
8206 return PyErr_SetFromWindowsErr(0);
8207
8208 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
8209}
8210#endif
8211
8212
Fred Drakec9680921999-12-13 16:37:25 +00008213/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
8214 * It maps strings representing configuration variable names to
8215 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00008216 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00008217 * rarely-used constants. There are three separate tables that use
8218 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00008219 *
8220 * This code is always included, even if none of the interfaces that
8221 * need it are included. The #if hackery needed to avoid it would be
8222 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00008223 */
8224struct constdef {
8225 char *name;
8226 long value;
8227};
8228
Fred Drake12c6e2d1999-12-14 21:25:03 +00008229static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008230conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00008231 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00008232{
Christian Heimes217cfd12007-12-02 14:31:20 +00008233 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008234 *valuep = PyLong_AS_LONG(arg);
8235 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00008236 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00008237 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00008238 /* look up the value in the table using a binary search */
8239 size_t lo = 0;
8240 size_t mid;
8241 size_t hi = tablesize;
8242 int cmp;
8243 const char *confname;
8244 if (!PyUnicode_Check(arg)) {
8245 PyErr_SetString(PyExc_TypeError,
8246 "configuration names must be strings or integers");
8247 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008248 }
Stefan Krah0e803b32010-11-26 16:16:47 +00008249 confname = _PyUnicode_AsString(arg);
8250 if (confname == NULL)
8251 return 0;
8252 while (lo < hi) {
8253 mid = (lo + hi) / 2;
8254 cmp = strcmp(confname, table[mid].name);
8255 if (cmp < 0)
8256 hi = mid;
8257 else if (cmp > 0)
8258 lo = mid + 1;
8259 else {
8260 *valuep = table[mid].value;
8261 return 1;
8262 }
8263 }
8264 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
8265 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00008266 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00008267}
8268
8269
8270#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8271static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008272#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008273 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008274#endif
8275#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008276 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008277#endif
Fred Drakec9680921999-12-13 16:37:25 +00008278#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008279 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008280#endif
8281#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00008282 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00008283#endif
8284#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00008285 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00008286#endif
8287#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00008288 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00008289#endif
8290#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008291 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008292#endif
8293#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00008294 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00008295#endif
8296#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00008298#endif
8299#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008300 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008301#endif
8302#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008303 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00008304#endif
8305#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008306 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008307#endif
8308#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008309 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00008310#endif
8311#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008312 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008313#endif
8314#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00008315 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00008316#endif
8317#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008318 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008319#endif
8320#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008321 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00008322#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00008323#ifdef _PC_ACL_ENABLED
8324 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
8325#endif
8326#ifdef _PC_MIN_HOLE_SIZE
8327 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
8328#endif
8329#ifdef _PC_ALLOC_SIZE_MIN
8330 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
8331#endif
8332#ifdef _PC_REC_INCR_XFER_SIZE
8333 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
8334#endif
8335#ifdef _PC_REC_MAX_XFER_SIZE
8336 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
8337#endif
8338#ifdef _PC_REC_MIN_XFER_SIZE
8339 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
8340#endif
8341#ifdef _PC_REC_XFER_ALIGN
8342 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
8343#endif
8344#ifdef _PC_SYMLINK_MAX
8345 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
8346#endif
8347#ifdef _PC_XATTR_ENABLED
8348 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
8349#endif
8350#ifdef _PC_XATTR_EXISTS
8351 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
8352#endif
8353#ifdef _PC_TIMESTAMP_RESOLUTION
8354 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
8355#endif
Fred Drakec9680921999-12-13 16:37:25 +00008356};
8357
Fred Drakec9680921999-12-13 16:37:25 +00008358static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008359conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008360{
8361 return conv_confname(arg, valuep, posix_constants_pathconf,
8362 sizeof(posix_constants_pathconf)
8363 / sizeof(struct constdef));
8364}
8365#endif
8366
8367#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008368PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008369"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008370Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008371If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008372
8373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008374posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008375{
8376 PyObject *result = NULL;
8377 int name, fd;
8378
Fred Drake12c6e2d1999-12-14 21:25:03 +00008379 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
8380 conv_path_confname, &name)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00008381 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008382
Stefan Krah0e803b32010-11-26 16:16:47 +00008383 errno = 0;
8384 limit = fpathconf(fd, name);
8385 if (limit == -1 && errno != 0)
8386 posix_error();
8387 else
8388 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008389 }
8390 return result;
8391}
8392#endif
8393
8394
8395#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008396PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008397"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00008398Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008399If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00008400
8401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008402posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008403{
8404 PyObject *result = NULL;
8405 int name;
8406 char *path;
8407
8408 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
8409 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008410 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00008411
Victor Stinner8c62be82010-05-06 00:08:46 +00008412 errno = 0;
8413 limit = pathconf(path, name);
8414 if (limit == -1 && errno != 0) {
8415 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00008416 /* could be a path or name problem */
8417 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008418 else
Stefan Krah99439262010-11-26 12:58:05 +00008419 posix_error_with_filename(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 }
8421 else
8422 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00008423 }
8424 return result;
8425}
8426#endif
8427
8428#ifdef HAVE_CONFSTR
8429static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00008430#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00008431 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00008432#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00008433#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008435#endif
8436#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00008438#endif
Fred Draked86ed291999-12-15 15:34:33 +00008439#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008440 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008441#endif
8442#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008443 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008444#endif
8445#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008446 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008447#endif
8448#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008450#endif
Fred Drakec9680921999-12-13 16:37:25 +00008451#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008452 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008453#endif
8454#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008455 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008456#endif
8457#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008458 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008459#endif
8460#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008461 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008462#endif
8463#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008465#endif
8466#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008467 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008468#endif
8469#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008470 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008471#endif
8472#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008474#endif
Fred Draked86ed291999-12-15 15:34:33 +00008475#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00008476 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00008477#endif
Fred Drakec9680921999-12-13 16:37:25 +00008478#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00008479 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00008480#endif
Fred Draked86ed291999-12-15 15:34:33 +00008481#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00008483#endif
8484#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008485 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00008486#endif
8487#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008488 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00008489#endif
8490#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008491 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00008492#endif
Fred Drakec9680921999-12-13 16:37:25 +00008493#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008494 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008495#endif
8496#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008497 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008498#endif
8499#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008500 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008501#endif
8502#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008503 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008504#endif
8505#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008506 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008507#endif
8508#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008509 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008510#endif
8511#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008512 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008513#endif
8514#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008515 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008516#endif
8517#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008518 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008519#endif
8520#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008521 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008522#endif
8523#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008524 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008525#endif
8526#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008527 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008528#endif
8529#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008530 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008531#endif
8532#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008533 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008534#endif
8535#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00008536 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00008537#endif
8538#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00008539 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00008540#endif
Fred Draked86ed291999-12-15 15:34:33 +00008541#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008542 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008543#endif
8544#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00008545 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00008546#endif
8547#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00008548 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00008549#endif
8550#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008551 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008552#endif
8553#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008554 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008555#endif
8556#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00008557 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00008558#endif
8559#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008560 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00008561#endif
8562#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00008563 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00008564#endif
8565#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00008566 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00008567#endif
8568#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00008569 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00008570#endif
8571#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00008572 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00008573#endif
8574#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008575 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00008576#endif
8577#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00008578 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00008579#endif
Fred Drakec9680921999-12-13 16:37:25 +00008580};
8581
8582static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008583conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008584{
8585 return conv_confname(arg, valuep, posix_constants_confstr,
8586 sizeof(posix_constants_confstr)
8587 / sizeof(struct constdef));
8588}
8589
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008590PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008591"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008592Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008593
8594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008595posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008596{
8597 PyObject *result = NULL;
8598 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00008599 char buffer[255];
Stefan Krah99439262010-11-26 12:58:05 +00008600 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008601
Victor Stinnercb043522010-09-10 23:49:04 +00008602 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
8603 return NULL;
8604
8605 errno = 0;
8606 len = confstr(name, buffer, sizeof(buffer));
8607 if (len == 0) {
8608 if (errno) {
8609 posix_error();
8610 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00008611 }
8612 else {
Victor Stinnercb043522010-09-10 23:49:04 +00008613 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00008614 }
8615 }
Victor Stinnercb043522010-09-10 23:49:04 +00008616
8617 if ((unsigned int)len >= sizeof(buffer)) {
8618 char *buf = PyMem_Malloc(len);
8619 if (buf == NULL)
8620 return PyErr_NoMemory();
8621 confstr(name, buf, len);
8622 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
8623 PyMem_Free(buf);
8624 }
8625 else
8626 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00008627 return result;
8628}
8629#endif
8630
8631
8632#ifdef HAVE_SYSCONF
8633static struct constdef posix_constants_sysconf[] = {
8634#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008635 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008636#endif
8637#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00008638 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008639#endif
8640#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008641 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008642#endif
8643#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008644 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008645#endif
8646#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008647 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008648#endif
8649#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00008650 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008651#endif
8652#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00008653 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008654#endif
8655#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00008656 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008657#endif
8658#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00008659 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008660#endif
8661#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00008662 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008663#endif
Fred Draked86ed291999-12-15 15:34:33 +00008664#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008665 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008666#endif
8667#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00008668 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008669#endif
Fred Drakec9680921999-12-13 16:37:25 +00008670#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008671 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008672#endif
Fred Drakec9680921999-12-13 16:37:25 +00008673#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008674 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008675#endif
8676#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008677 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008678#endif
8679#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008680 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008681#endif
8682#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008683 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008684#endif
8685#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008686 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008687#endif
Fred Draked86ed291999-12-15 15:34:33 +00008688#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008689 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008690#endif
Fred Drakec9680921999-12-13 16:37:25 +00008691#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008692 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008693#endif
8694#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008695 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008696#endif
8697#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008698 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008699#endif
8700#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008701 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008702#endif
8703#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008704 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008705#endif
Fred Draked86ed291999-12-15 15:34:33 +00008706#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00008707 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008708#endif
Fred Drakec9680921999-12-13 16:37:25 +00008709#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008710 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008711#endif
8712#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008713 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008714#endif
8715#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008716 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008717#endif
8718#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008719 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008720#endif
8721#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008722 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008723#endif
8724#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008725 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008726#endif
8727#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008728 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008729#endif
8730#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008731 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008732#endif
8733#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008734 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008735#endif
8736#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008737 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008738#endif
8739#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008740 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008741#endif
8742#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008743 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008744#endif
8745#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008746 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008747#endif
8748#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008749 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008750#endif
8751#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008752 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008753#endif
8754#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008755 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008756#endif
8757#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008758 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008759#endif
8760#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008761 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008762#endif
8763#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008764 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008765#endif
8766#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008768#endif
8769#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008770 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008771#endif
8772#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008773 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008774#endif
8775#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00008776 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008777#endif
Fred Draked86ed291999-12-15 15:34:33 +00008778#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00008779 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008780#endif
Fred Drakec9680921999-12-13 16:37:25 +00008781#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008782 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008783#endif
8784#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008785 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008786#endif
8787#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008788 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008789#endif
Fred Draked86ed291999-12-15 15:34:33 +00008790#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008791 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008792#endif
Fred Drakec9680921999-12-13 16:37:25 +00008793#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00008794 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008795#endif
Fred Draked86ed291999-12-15 15:34:33 +00008796#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00008797 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008798#endif
8799#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00008800 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008801#endif
Fred Drakec9680921999-12-13 16:37:25 +00008802#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008803 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008804#endif
8805#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008806 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008807#endif
8808#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008809 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008810#endif
8811#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008812 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008813#endif
Fred Draked86ed291999-12-15 15:34:33 +00008814#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00008815 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008816#endif
Fred Drakec9680921999-12-13 16:37:25 +00008817#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00008818 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008819#endif
8820#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00008821 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008822#endif
8823#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008824 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008825#endif
8826#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008827 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008828#endif
8829#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008830 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008831#endif
8832#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00008833 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008834#endif
8835#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00008836 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008837#endif
Fred Draked86ed291999-12-15 15:34:33 +00008838#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00008839 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008840#endif
Fred Drakec9680921999-12-13 16:37:25 +00008841#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008842 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008843#endif
8844#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008845 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008846#endif
Fred Draked86ed291999-12-15 15:34:33 +00008847#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008848 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008849#endif
Fred Drakec9680921999-12-13 16:37:25 +00008850#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008851 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008852#endif
8853#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008854 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008855#endif
8856#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008857 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008858#endif
8859#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008860 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008861#endif
8862#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008863 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008864#endif
8865#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008866 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008867#endif
8868#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008869 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008870#endif
8871#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008872 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008873#endif
8874#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008875 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008876#endif
Fred Draked86ed291999-12-15 15:34:33 +00008877#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00008878 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008879#endif
8880#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00008881 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008882#endif
Fred Drakec9680921999-12-13 16:37:25 +00008883#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00008884 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008885#endif
8886#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008887 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008888#endif
8889#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008890 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008891#endif
8892#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00008893 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008894#endif
8895#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008896 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008897#endif
8898#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00008899 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008900#endif
8901#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00008902 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008903#endif
8904#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00008905 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008906#endif
8907#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008908 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008909#endif
8910#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00008911 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008912#endif
8913#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00008914 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008915#endif
8916#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008917 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008918#endif
8919#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008920 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008921#endif
8922#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008924#endif
8925#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00008926 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008927#endif
8928#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00008929 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008930#endif
8931#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00008932 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008933#endif
8934#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00008935 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008936#endif
8937#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00008938 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008939#endif
8940#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00008941 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008942#endif
8943#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008944 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008945#endif
8946#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008947 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008948#endif
8949#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00008950 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008951#endif
8952#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008953 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008954#endif
8955#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008956 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008957#endif
8958#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008959 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008960#endif
8961#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00008962 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008963#endif
8964#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008965 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008966#endif
8967#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008968 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008969#endif
8970#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00008971 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008972#endif
8973#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008974 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008975#endif
8976#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008977 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008978#endif
8979#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008980 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008981#endif
8982#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008983 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008984#endif
8985#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00008986 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008987#endif
Fred Draked86ed291999-12-15 15:34:33 +00008988#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00008989 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008990#endif
Fred Drakec9680921999-12-13 16:37:25 +00008991#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00008992 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008993#endif
8994#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008995 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008996#endif
8997#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00008998 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008999#endif
9000#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009001 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009002#endif
9003#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009004 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009005#endif
9006#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009007 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009008#endif
9009#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00009010 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00009011#endif
9012#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009014#endif
9015#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009016 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009017#endif
9018#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009019 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009020#endif
9021#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009022 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009023#endif
9024#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009025 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00009026#endif
9027#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009028 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00009029#endif
9030#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00009031 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00009032#endif
9033#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00009035#endif
9036#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009037 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009038#endif
9039#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009041#endif
9042#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00009044#endif
9045#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009046 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009047#endif
9048#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009049 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009050#endif
9051#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009052 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009053#endif
9054#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009056#endif
9057#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009058 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009059#endif
9060#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009061 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009062#endif
9063#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00009065#endif
9066#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009067 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009068#endif
9069#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009070 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009071#endif
9072#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009074#endif
9075#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009076 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009077#endif
9078#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00009080#endif
9081#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009083#endif
9084#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00009086#endif
9087#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00009089#endif
9090#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00009092#endif
9093#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00009094 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00009095#endif
9096#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00009097 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00009098#endif
9099#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00009100 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00009101#endif
9102#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00009103 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00009104#endif
9105#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00009106 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00009107#endif
9108#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00009110#endif
9111#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009112 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009113#endif
9114#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009115 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009116#endif
9117#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00009118 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00009119#endif
9120#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00009122#endif
9123#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00009125#endif
9126};
9127
9128static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009129conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009130{
9131 return conv_confname(arg, valuep, posix_constants_sysconf,
9132 sizeof(posix_constants_sysconf)
9133 / sizeof(struct constdef));
9134}
9135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009136PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009137"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009138Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00009139
9140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009141posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00009142{
9143 PyObject *result = NULL;
9144 int name;
9145
9146 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
9147 int value;
9148
9149 errno = 0;
9150 value = sysconf(name);
9151 if (value == -1 && errno != 0)
9152 posix_error();
9153 else
Christian Heimes217cfd12007-12-02 14:31:20 +00009154 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00009155 }
9156 return result;
9157}
9158#endif
9159
9160
Fred Drakebec628d1999-12-15 18:31:10 +00009161/* This code is used to ensure that the tables of configuration value names
9162 * are in sorted order as required by conv_confname(), and also to build the
9163 * the exported dictionaries that are used to publish information about the
9164 * names available on the host platform.
9165 *
9166 * Sorting the table at runtime ensures that the table is properly ordered
9167 * when used, even for platforms we're not able to test on. It also makes
9168 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00009169 */
Fred Drakebec628d1999-12-15 18:31:10 +00009170
9171static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009172cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00009173{
9174 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009175 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00009176 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00009178
9179 return strcmp(c1->name, c2->name);
9180}
9181
9182static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009183setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00009184 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009185{
Fred Drakebec628d1999-12-15 18:31:10 +00009186 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00009187 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00009188
9189 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
9190 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00009191 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00009192 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009193
Barry Warsaw3155db32000-04-13 15:20:40 +00009194 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009195 PyObject *o = PyLong_FromLong(table[i].value);
9196 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
9197 Py_XDECREF(o);
9198 Py_DECREF(d);
9199 return -1;
9200 }
9201 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00009202 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009203 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00009204}
9205
Fred Drakebec628d1999-12-15 18:31:10 +00009206/* Return -1 on failure, 0 on success. */
9207static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009208setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00009209{
9210#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00009211 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00009212 sizeof(posix_constants_pathconf)
9213 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009214 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009215 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009216#endif
9217#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00009218 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00009219 sizeof(posix_constants_confstr)
9220 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009221 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009222 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009223#endif
9224#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00009225 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00009226 sizeof(posix_constants_sysconf)
9227 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00009228 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +00009229 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00009230#endif
Fred Drakebec628d1999-12-15 18:31:10 +00009231 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00009232}
Fred Draked86ed291999-12-15 15:34:33 +00009233
9234
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009235PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00009236"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009237Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009238in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009239
9240static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009241posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009242{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009243 abort();
9244 /*NOTREACHED*/
9245 Py_FatalError("abort() called from Python code didn't abort!");
9246 return NULL;
9247}
Fred Drakebec628d1999-12-15 18:31:10 +00009248
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009249#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009250PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00009251"startfile(filepath [, operation]) - Start a file with its associated\n\
9252application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009253\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00009254When \"operation\" is not specified or \"open\", this acts like\n\
9255double-clicking the file in Explorer, or giving the file name as an\n\
9256argument to the DOS \"start\" command: the file is opened with whatever\n\
9257application (if any) its extension is associated.\n\
9258When another \"operation\" is given, it specifies what should be done with\n\
9259the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00009260\n\
9261startfile returns as soon as the associated application is launched.\n\
9262There is no option to wait for the application to close, and no way\n\
9263to retrieve the application's exit status.\n\
9264\n\
9265The filepath is relative to the current directory. If you want to use\n\
9266an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00009267the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00009268
9269static PyObject *
9270win32_startfile(PyObject *self, PyObject *args)
9271{
Victor Stinner8c62be82010-05-06 00:08:46 +00009272 PyObject *ofilepath;
9273 char *filepath;
9274 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +02009275 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00009277
Victor Stinnereb5657a2011-09-30 01:44:27 +02009278 PyObject *unipath, *uoperation = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 if (!PyArg_ParseTuple(args, "U|s:startfile",
9280 &unipath, &operation)) {
9281 PyErr_Clear();
9282 goto normal;
9283 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009284
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009286 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +00009287 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +02009288 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009289 PyErr_Clear();
9290 operation = NULL;
9291 goto normal;
9292 }
9293 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00009294
Victor Stinnereb5657a2011-09-30 01:44:27 +02009295 wpath = PyUnicode_AsUnicode(unipath);
9296 if (wpath == NULL)
9297 goto normal;
9298 if (uoperation) {
9299 woperation = PyUnicode_AsUnicode(uoperation);
9300 if (woperation == NULL)
9301 goto normal;
9302 }
9303 else
9304 woperation = NULL;
9305
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 Py_BEGIN_ALLOW_THREADS
Victor Stinnereb5657a2011-09-30 01:44:27 +02009307 rc = ShellExecuteW((HWND)0, woperation, wpath,
9308 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 Py_END_ALLOW_THREADS
9310
Victor Stinnereb5657a2011-09-30 01:44:27 +02009311 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02009313 win32_error_object("startfile", unipath);
9314 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00009315 }
9316 Py_INCREF(Py_None);
9317 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009318
9319normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00009320 if (!PyArg_ParseTuple(args, "O&|s:startfile",
9321 PyUnicode_FSConverter, &ofilepath,
9322 &operation))
9323 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01009324 if (win32_warn_bytes_api()) {
9325 Py_DECREF(ofilepath);
9326 return NULL;
9327 }
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 filepath = PyBytes_AsString(ofilepath);
9329 Py_BEGIN_ALLOW_THREADS
9330 rc = ShellExecute((HWND)0, operation, filepath,
9331 NULL, NULL, SW_SHOWNORMAL);
9332 Py_END_ALLOW_THREADS
9333 if (rc <= (HINSTANCE)32) {
9334 PyObject *errval = win32_error("startfile", filepath);
9335 Py_DECREF(ofilepath);
9336 return errval;
9337 }
9338 Py_DECREF(ofilepath);
9339 Py_INCREF(Py_None);
9340 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00009341}
9342#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009343
Martin v. Löwis438b5342002-12-27 10:16:42 +00009344#ifdef HAVE_GETLOADAVG
9345PyDoc_STRVAR(posix_getloadavg__doc__,
9346"getloadavg() -> (float, float, float)\n\n\
9347Return the number of processes in the system run queue averaged over\n\
9348the last 1, 5, and 15 minutes or raises OSError if the load average\n\
9349was unobtainable");
9350
9351static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00009352posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00009353{
9354 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00009355 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009356 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
9357 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00009358 } else
Stefan Krah0e803b32010-11-26 16:16:47 +00009359 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00009360}
9361#endif
9362
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009363#ifdef MS_WINDOWS
9364
9365PyDoc_STRVAR(win32_urandom__doc__,
9366"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009367Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009368
9369typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
9370 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
9371 DWORD dwFlags );
9372typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
9373 BYTE *pbBuffer );
9374
9375static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00009376/* This handle is never explicitly released. Instead, the operating
9377 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009378static HCRYPTPROV hCryptProv = 0;
9379
Tim Peters4ad82172004-08-30 17:02:04 +00009380static PyObject*
9381win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009382{
Victor Stinner8c62be82010-05-06 00:08:46 +00009383 int howMany;
9384 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009385
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 /* Read arguments */
9387 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9388 return NULL;
9389 if (howMany < 0)
9390 return PyErr_Format(PyExc_ValueError,
9391 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009392
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 if (hCryptProv == 0) {
9394 HINSTANCE hAdvAPI32 = NULL;
9395 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009396
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 /* Obtain handle to the DLL containing CryptoAPI
9398 This should not fail */
Martin v. Löwis50590f12012-01-14 17:54:09 +01009399 hAdvAPI32 = GetModuleHandleW(L"advapi32.dll");
Victor Stinner8c62be82010-05-06 00:08:46 +00009400 if(hAdvAPI32 == NULL)
9401 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009402
Victor Stinner8c62be82010-05-06 00:08:46 +00009403 /* Obtain pointers to the CryptoAPI functions
9404 This will fail on some early versions of Win95 */
9405 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
9406 hAdvAPI32,
9407 "CryptAcquireContextA");
9408 if (pCryptAcquireContext == NULL)
9409 return PyErr_Format(PyExc_NotImplementedError,
9410 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009411
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
9413 hAdvAPI32, "CryptGenRandom");
9414 if (pCryptGenRandom == NULL)
9415 return PyErr_Format(PyExc_NotImplementedError,
9416 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009417
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 /* Acquire context */
9419 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
9420 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
9421 return win32_error("CryptAcquireContext", NULL);
9422 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009423
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 /* Allocate bytes */
9425 result = PyBytes_FromStringAndSize(NULL, howMany);
9426 if (result != NULL) {
9427 /* Get random data */
9428 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
9429 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
9430 PyBytes_AS_STRING(result))) {
9431 Py_DECREF(result);
9432 return win32_error("CryptGenRandom", NULL);
9433 }
9434 }
9435 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009436}
9437#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009438
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009439PyDoc_STRVAR(device_encoding__doc__,
9440"device_encoding(fd) -> str\n\n\
9441Return a string describing the encoding of the device\n\
9442if the output is a terminal; else return None.");
9443
9444static PyObject *
9445device_encoding(PyObject *self, PyObject *args)
9446{
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 int fd;
Victor Stinner7870bdf2011-05-23 18:12:52 +02009448#if defined(MS_WINDOWS) || defined(MS_WIN64)
9449 UINT cp;
9450#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
9452 return NULL;
9453 if (!_PyVerify_fd(fd) || !isatty(fd)) {
9454 Py_INCREF(Py_None);
9455 return Py_None;
9456 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009457#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner7870bdf2011-05-23 18:12:52 +02009458 if (fd == 0)
9459 cp = GetConsoleCP();
9460 else if (fd == 1 || fd == 2)
9461 cp = GetConsoleOutputCP();
9462 else
9463 cp = 0;
9464 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
9465 has no console */
9466 if (cp != 0)
9467 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009468#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {
9470 char *codeset = nl_langinfo(CODESET);
9471 if (codeset != NULL && codeset[0] != 0)
9472 return PyUnicode_FromString(codeset);
9473 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009474#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 Py_INCREF(Py_None);
9476 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00009477}
9478
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009479#ifdef __VMS
9480/* Use openssl random routine */
9481#include <openssl/rand.h>
9482PyDoc_STRVAR(vms_urandom__doc__,
9483"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00009484Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009485
9486static PyObject*
9487vms_urandom(PyObject *self, PyObject *args)
9488{
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 int howMany;
9490 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009491
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 /* Read arguments */
9493 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
9494 return NULL;
9495 if (howMany < 0)
9496 return PyErr_Format(PyExc_ValueError,
9497 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009498
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 /* Allocate bytes */
9500 result = PyBytes_FromStringAndSize(NULL, howMany);
9501 if (result != NULL) {
9502 /* Get random data */
9503 if (RAND_pseudo_bytes((unsigned char*)
9504 PyBytes_AS_STRING(result),
9505 howMany) < 0) {
9506 Py_DECREF(result);
9507 return PyErr_Format(PyExc_ValueError,
9508 "RAND_pseudo_bytes");
9509 }
9510 }
9511 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00009512}
9513#endif
9514
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009515#ifdef HAVE_SETRESUID
9516PyDoc_STRVAR(posix_setresuid__doc__,
9517"setresuid(ruid, euid, suid)\n\n\
9518Set the current process's real, effective, and saved user ids.");
9519
9520static PyObject*
9521posix_setresuid (PyObject *self, PyObject *args)
9522{
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 /* We assume uid_t is no larger than a long. */
9524 long ruid, euid, suid;
9525 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
9526 return NULL;
9527 if (setresuid(ruid, euid, suid) < 0)
9528 return posix_error();
9529 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009530}
9531#endif
9532
9533#ifdef HAVE_SETRESGID
9534PyDoc_STRVAR(posix_setresgid__doc__,
9535"setresgid(rgid, egid, sgid)\n\n\
9536Set the current process's real, effective, and saved group ids.");
9537
9538static PyObject*
9539posix_setresgid (PyObject *self, PyObject *args)
9540{
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 /* We assume uid_t is no larger than a long. */
9542 long rgid, egid, sgid;
9543 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
9544 return NULL;
9545 if (setresgid(rgid, egid, sgid) < 0)
9546 return posix_error();
9547 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009548}
9549#endif
9550
9551#ifdef HAVE_GETRESUID
9552PyDoc_STRVAR(posix_getresuid__doc__,
9553"getresuid() -> (ruid, euid, suid)\n\n\
9554Get tuple of the current process's real, effective, and saved user ids.");
9555
9556static PyObject*
9557posix_getresuid (PyObject *self, PyObject *noargs)
9558{
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 uid_t ruid, euid, suid;
9560 long l_ruid, l_euid, l_suid;
9561 if (getresuid(&ruid, &euid, &suid) < 0)
9562 return posix_error();
9563 /* Force the values into long's as we don't know the size of uid_t. */
9564 l_ruid = ruid;
9565 l_euid = euid;
9566 l_suid = suid;
9567 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009568}
9569#endif
9570
9571#ifdef HAVE_GETRESGID
9572PyDoc_STRVAR(posix_getresgid__doc__,
9573"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00009574Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009575
9576static PyObject*
9577posix_getresgid (PyObject *self, PyObject *noargs)
9578{
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 uid_t rgid, egid, sgid;
9580 long l_rgid, l_egid, l_sgid;
9581 if (getresgid(&rgid, &egid, &sgid) < 0)
9582 return posix_error();
9583 /* Force the values into long's as we don't know the size of uid_t. */
9584 l_rgid = rgid;
9585 l_egid = egid;
9586 l_sgid = sgid;
9587 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00009588}
9589#endif
9590
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009591/* Posix *at family of functions:
9592 faccessat, fchmodat, fchownat, fstatat, futimesat,
9593 linkat, mkdirat, mknodat, openat, readlinkat, renameat, symlinkat,
9594 unlinkat, utimensat, mkfifoat */
9595
9596#ifdef HAVE_FACCESSAT
9597PyDoc_STRVAR(posix_faccessat__doc__,
9598"faccessat(dirfd, path, mode, flags=0) -> True if granted, False otherwise\n\n\
9599Like access() but if path is relative, it is taken as relative to dirfd.\n\
9600flags is optional and can be constructed by ORing together zero or more\n\
9601of these values: AT_SYMLINK_NOFOLLOW, AT_EACCESS.\n\
9602If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9603is interpreted relative to the current working directory.");
9604
9605static PyObject *
9606posix_faccessat(PyObject *self, PyObject *args)
9607{
9608 PyObject *opath;
9609 char *path;
9610 int mode;
9611 int res;
9612 int dirfd, flags = 0;
9613 if (!PyArg_ParseTuple(args, "iO&i|i:faccessat",
9614 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9615 return NULL;
9616 path = PyBytes_AsString(opath);
9617 Py_BEGIN_ALLOW_THREADS
9618 res = faccessat(dirfd, path, mode, flags);
9619 Py_END_ALLOW_THREADS
9620 Py_DECREF(opath);
9621 return PyBool_FromLong(res == 0);
9622}
9623#endif
9624
9625#ifdef HAVE_FCHMODAT
9626PyDoc_STRVAR(posix_fchmodat__doc__,
9627"fchmodat(dirfd, path, mode, flags=0)\n\n\
9628Like chmod() but if path is relative, it is taken as relative to dirfd.\n\
9629flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9630If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9631is interpreted relative to the current working directory.");
9632
9633static PyObject *
9634posix_fchmodat(PyObject *self, PyObject *args)
9635{
9636 int dirfd, mode, res;
9637 int flags = 0;
9638 PyObject *opath;
9639 char *path;
9640
9641 if (!PyArg_ParseTuple(args, "iO&i|i:fchmodat",
9642 &dirfd, PyUnicode_FSConverter, &opath, &mode, &flags))
9643 return NULL;
9644
9645 path = PyBytes_AsString(opath);
9646
9647 Py_BEGIN_ALLOW_THREADS
9648 res = fchmodat(dirfd, path, mode, flags);
9649 Py_END_ALLOW_THREADS
9650 Py_DECREF(opath);
9651 if (res < 0)
9652 return posix_error();
9653 Py_RETURN_NONE;
9654}
9655#endif /* HAVE_FCHMODAT */
9656
9657#ifdef HAVE_FCHOWNAT
9658PyDoc_STRVAR(posix_fchownat__doc__,
9659"fchownat(dirfd, path, uid, gid, flags=0)\n\n\
9660Like chown() but if path is relative, it is taken as relative to dirfd.\n\
9661flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9662If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9663is interpreted relative to the current working directory.");
9664
9665static PyObject *
9666posix_fchownat(PyObject *self, PyObject *args)
9667{
9668 PyObject *opath;
9669 int dirfd, res;
9670 long uid, gid;
9671 int flags = 0;
9672 char *path;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02009673
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009674 if (!PyArg_ParseTuple(args, "iO&ll|i:fchownat",
9675 &dirfd, PyUnicode_FSConverter, &opath, &uid, &gid, &flags))
9676 return NULL;
9677
9678 path = PyBytes_AsString(opath);
9679
9680 Py_BEGIN_ALLOW_THREADS
9681 res = fchownat(dirfd, path, (uid_t) uid, (gid_t) gid, flags);
9682 Py_END_ALLOW_THREADS
9683 Py_DECREF(opath);
9684 if (res < 0)
9685 return posix_error();
9686 Py_RETURN_NONE;
9687}
9688#endif /* HAVE_FCHOWNAT */
9689
9690#ifdef HAVE_FSTATAT
9691PyDoc_STRVAR(posix_fstatat__doc__,
Victor Stinnerccd57152012-02-08 14:31:50 +01009692"fstatat(dirfd, path, flags=0, timestamp=None) -> stat result\n\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009693Like stat() but if path is relative, it is taken as relative to dirfd.\n\
9694flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
9695If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9696is interpreted relative to the current working directory.");
9697
9698static PyObject *
Victor Stinnerccd57152012-02-08 14:31:50 +01009699posix_fstatat(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009700{
Victor Stinnerccd57152012-02-08 14:31:50 +01009701 static char *kwlist[] = {"dirfd", "path", "flags", "timestamp", NULL};
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009702 PyObject *opath;
9703 char *path;
9704 STRUCT_STAT st;
9705 int dirfd, res, flags = 0;
Victor Stinnerccd57152012-02-08 14:31:50 +01009706 PyObject *timestamp = NULL;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009707
Victor Stinnerccd57152012-02-08 14:31:50 +01009708 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|iO:fstatat", kwlist,
9709 &dirfd, PyUnicode_FSConverter, &opath,
9710 &flags, &timestamp))
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009711 return NULL;
9712 path = PyBytes_AsString(opath);
9713
9714 Py_BEGIN_ALLOW_THREADS
9715 res = fstatat(dirfd, path, &st, flags);
9716 Py_END_ALLOW_THREADS
9717 Py_DECREF(opath);
9718 if (res != 0)
9719 return posix_error();
9720
Victor Stinnerccd57152012-02-08 14:31:50 +01009721 return _pystat_fromstructstat(&st, timestamp);
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009722}
9723#endif
9724
9725#ifdef HAVE_FUTIMESAT
9726PyDoc_STRVAR(posix_futimesat__doc__,
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009727"futimesat(dirfd, path[, (atime, mtime)])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009728Like utime() but if path is relative, it is taken as relative to dirfd.\n\
9729If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9730is interpreted relative to the current working directory.");
9731
9732static PyObject *
9733posix_futimesat(PyObject *self, PyObject *args)
9734{
9735 PyObject *opath;
9736 char *path;
9737 int res, dirfd;
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009738 PyObject* arg = Py_None;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009739 time_t atime, mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009740 long ansec, mnsec;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009741
Brian Curtin7ef53ef2011-11-07 14:38:24 -06009742 if (!PyArg_ParseTuple(args, "iO&|O:futimesat",
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009743 &dirfd, PyUnicode_FSConverter, &opath, &arg))
9744 return NULL;
9745 path = PyBytes_AsString(opath);
9746 if (arg == Py_None) {
9747 /* optional time values not given */
9748 Py_BEGIN_ALLOW_THREADS
9749 res = futimesat(dirfd, path, NULL);
9750 Py_END_ALLOW_THREADS
9751 }
9752 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
9753 PyErr_SetString(PyExc_TypeError,
9754 "futimesat() arg 3 must be a tuple (atime, mtime)");
9755 Py_DECREF(opath);
9756 return NULL;
9757 }
9758 else {
9759 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Victor Stinnera2f7c002012-02-08 03:36:25 +01009760 &atime, &ansec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009761 Py_DECREF(opath);
9762 return NULL;
9763 }
9764 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Victor Stinnera2f7c002012-02-08 03:36:25 +01009765 &mtime, &mnsec) == -1) {
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009766 Py_DECREF(opath);
9767 return NULL;
9768 }
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009769
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009770 Py_BEGIN_ALLOW_THREADS
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009771 {
9772#ifdef HAVE_UTIMENSAT
9773 struct timespec buf[2];
9774 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009775 buf[0].tv_nsec = ansec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009776 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009777 buf[1].tv_nsec = mnsec;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009778 res = utimensat(dirfd, path, buf, 0);
9779#else
9780 struct timeval buf[2];
9781 buf[0].tv_sec = atime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009782 buf[0].tv_usec = ansec / 1000;
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009783 buf[1].tv_sec = mtime;
Victor Stinnera2f7c002012-02-08 03:36:25 +01009784 buf[1].tv_usec = mnsec / 1000;
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009785 res = futimesat(dirfd, path, buf);
Larry Hastings9e3e70b2011-09-08 19:29:07 -07009786#endif
9787 }
Antoine Pitrouf65132d2011-02-25 23:25:17 +00009788 Py_END_ALLOW_THREADS
9789 }
9790 Py_DECREF(opath);
9791 if (res < 0) {
9792 return posix_error();
9793 }
9794 Py_RETURN_NONE;
9795}
9796#endif
9797
9798#ifdef HAVE_LINKAT
9799PyDoc_STRVAR(posix_linkat__doc__,
9800"linkat(srcfd, srcpath, dstfd, dstpath, flags=0)\n\n\
9801Like link() but if srcpath is relative, it is taken as relative to srcfd\n\
9802and if dstpath is relative, it is taken as relative to dstfd.\n\
9803flags is optional and may be 0 or AT_SYMLINK_FOLLOW.\n\
9804If srcpath is relative and srcfd is the special value AT_FDCWD, then\n\
9805srcpath is interpreted relative to the current working directory. This\n\
9806also applies for dstpath.");
9807
9808static PyObject *
9809posix_linkat(PyObject *self, PyObject *args)
9810{
9811 PyObject *osrc, *odst;
9812 char *src, *dst;
9813 int res, srcfd, dstfd;
9814 int flags = 0;
9815
9816 if (!PyArg_ParseTuple(args, "iO&iO&|i:linkat",
9817 &srcfd, PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst, &flags))
9818 return NULL;
9819 src = PyBytes_AsString(osrc);
9820 dst = PyBytes_AsString(odst);
9821 Py_BEGIN_ALLOW_THREADS
9822 res = linkat(srcfd, src, dstfd, dst, flags);
9823 Py_END_ALLOW_THREADS
9824 Py_DECREF(osrc);
9825 Py_DECREF(odst);
9826 if (res < 0)
9827 return posix_error();
9828 Py_RETURN_NONE;
9829}
9830#endif /* HAVE_LINKAT */
9831
9832#ifdef HAVE_MKDIRAT
9833PyDoc_STRVAR(posix_mkdirat__doc__,
9834"mkdirat(dirfd, path, mode=0o777)\n\n\
9835Like mkdir() but if path is relative, it is taken as relative to dirfd.\n\
9836If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9837is interpreted relative to the current working directory.");
9838
9839static PyObject *
9840posix_mkdirat(PyObject *self, PyObject *args)
9841{
9842 int res, dirfd;
9843 PyObject *opath;
9844 char *path;
9845 int mode = 0777;
9846
9847 if (!PyArg_ParseTuple(args, "iO&|i:mkdirat",
9848 &dirfd, PyUnicode_FSConverter, &opath, &mode))
9849 return NULL;
9850 path = PyBytes_AsString(opath);
9851 Py_BEGIN_ALLOW_THREADS
9852 res = mkdirat(dirfd, path, mode);
9853 Py_END_ALLOW_THREADS
9854 Py_DECREF(opath);
9855 if (res < 0)
9856 return posix_error();
9857 Py_RETURN_NONE;
9858}
9859#endif
9860
9861#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
9862PyDoc_STRVAR(posix_mknodat__doc__,
9863"mknodat(dirfd, path, mode=0o600, device=0)\n\n\
9864Like mknod() but if path is relative, it is taken as relative to dirfd.\n\
9865If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9866is interpreted relative to the current working directory.");
9867
9868static PyObject *
9869posix_mknodat(PyObject *self, PyObject *args)
9870{
9871 PyObject *opath;
9872 char *filename;
9873 int mode = 0600;
9874 int device = 0;
9875 int res, dirfd;
9876 if (!PyArg_ParseTuple(args, "iO&|ii:mknodat", &dirfd,
9877 PyUnicode_FSConverter, &opath, &mode, &device))
9878 return NULL;
9879 filename = PyBytes_AS_STRING(opath);
9880 Py_BEGIN_ALLOW_THREADS
9881 res = mknodat(dirfd, filename, mode, device);
9882 Py_END_ALLOW_THREADS
9883 Py_DECREF(opath);
9884 if (res < 0)
9885 return posix_error();
9886 Py_RETURN_NONE;
9887}
9888#endif
9889
9890#ifdef HAVE_OPENAT
9891PyDoc_STRVAR(posix_openat__doc__,
9892"openat(dirfd, path, flag, mode=0o777) -> fd\n\n\
9893Like open() but if path is relative, it is taken as relative to dirfd.\n\
9894If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9895is interpreted relative to the current working directory.");
9896
9897static PyObject *
9898posix_openat(PyObject *self, PyObject *args)
9899{
9900 PyObject *ofile;
9901 char *file;
9902 int flag, dirfd, fd;
9903 int mode = 0777;
9904
9905 if (!PyArg_ParseTuple(args, "iO&i|i:openat",
9906 &dirfd, PyUnicode_FSConverter, &ofile,
9907 &flag, &mode))
9908 return NULL;
9909 file = PyBytes_AsString(ofile);
9910 Py_BEGIN_ALLOW_THREADS
9911 fd = openat(dirfd, file, flag, mode);
9912 Py_END_ALLOW_THREADS
9913 Py_DECREF(ofile);
9914 if (fd < 0)
9915 return posix_error();
9916 return PyLong_FromLong((long)fd);
9917}
9918#endif
9919
9920#ifdef HAVE_READLINKAT
9921PyDoc_STRVAR(posix_readlinkat__doc__,
9922"readlinkat(dirfd, path) -> path\n\n\
9923Like readlink() but if path is relative, it is taken as relative to dirfd.\n\
9924If path is relative and dirfd is the special value AT_FDCWD, then path\n\
9925is interpreted relative to the current working directory.");
9926
9927static PyObject *
9928posix_readlinkat(PyObject *self, PyObject *args)
9929{
9930 PyObject *v, *opath;
9931 char buf[MAXPATHLEN];
9932 char *path;
9933 int n, dirfd;
9934 int arg_is_unicode = 0;
9935
9936 if (!PyArg_ParseTuple(args, "iO&:readlinkat",
9937 &dirfd, PyUnicode_FSConverter, &opath))
9938 return NULL;
9939 path = PyBytes_AsString(opath);
9940 v = PySequence_GetItem(args, 1);
9941 if (v == NULL) {
9942 Py_DECREF(opath);
9943 return NULL;
9944 }
9945
9946 if (PyUnicode_Check(v)) {
9947 arg_is_unicode = 1;
9948 }
9949 Py_DECREF(v);
9950
9951 Py_BEGIN_ALLOW_THREADS
9952 n = readlinkat(dirfd, path, buf, (int) sizeof buf);
9953 Py_END_ALLOW_THREADS
9954 Py_DECREF(opath);
9955 if (n < 0)
9956 return posix_error();
9957
9958 if (arg_is_unicode)
9959 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
9960 else
9961 return PyBytes_FromStringAndSize(buf, n);
9962}
9963#endif /* HAVE_READLINKAT */
9964
9965#ifdef HAVE_RENAMEAT
9966PyDoc_STRVAR(posix_renameat__doc__,
9967"renameat(olddirfd, oldpath, newdirfd, newpath)\n\n\
9968Like rename() but if oldpath is relative, it is taken as relative to\n\
9969olddirfd and if newpath is relative, it is taken as relative to newdirfd.\n\
9970If oldpath is relative and olddirfd is the special value AT_FDCWD, then\n\
9971oldpath is interpreted relative to the current working directory. This\n\
9972also applies for newpath.");
9973
9974static PyObject *
9975posix_renameat(PyObject *self, PyObject *args)
9976{
9977 int res;
9978 PyObject *opathold, *opathnew;
9979 char *opath, *npath;
9980 int oldfd, newfd;
9981
9982 if (!PyArg_ParseTuple(args, "iO&iO&:renameat",
9983 &oldfd, PyUnicode_FSConverter, &opathold, &newfd, PyUnicode_FSConverter, &opathnew))
9984 return NULL;
9985 opath = PyBytes_AsString(opathold);
9986 npath = PyBytes_AsString(opathnew);
9987 Py_BEGIN_ALLOW_THREADS
9988 res = renameat(oldfd, opath, newfd, npath);
9989 Py_END_ALLOW_THREADS
9990 Py_DECREF(opathold);
9991 Py_DECREF(opathnew);
9992 if (res < 0)
9993 return posix_error();
9994 Py_RETURN_NONE;
9995}
9996#endif
9997
9998#if HAVE_SYMLINKAT
9999PyDoc_STRVAR(posix_symlinkat__doc__,
10000"symlinkat(src, dstfd, dst)\n\n\
10001Like symlink() but if dst is relative, it is taken as relative to dstfd.\n\
10002If dst is relative and dstfd is the special value AT_FDCWD, then dst\n\
10003is interpreted relative to the current working directory.");
10004
10005static PyObject *
10006posix_symlinkat(PyObject *self, PyObject *args)
10007{
10008 int res, dstfd;
10009 PyObject *osrc, *odst;
10010 char *src, *dst;
10011
10012 if (!PyArg_ParseTuple(args, "O&iO&:symlinkat",
10013 PyUnicode_FSConverter, &osrc, &dstfd, PyUnicode_FSConverter, &odst))
10014 return NULL;
10015 src = PyBytes_AsString(osrc);
10016 dst = PyBytes_AsString(odst);
10017 Py_BEGIN_ALLOW_THREADS
10018 res = symlinkat(src, dstfd, dst);
10019 Py_END_ALLOW_THREADS
10020 Py_DECREF(osrc);
10021 Py_DECREF(odst);
10022 if (res < 0)
10023 return posix_error();
10024 Py_RETURN_NONE;
10025}
10026#endif /* HAVE_SYMLINKAT */
10027
10028#ifdef HAVE_UNLINKAT
10029PyDoc_STRVAR(posix_unlinkat__doc__,
10030"unlinkat(dirfd, path, flags=0)\n\n\
10031Like unlink() but if path is relative, it is taken as relative to dirfd.\n\
10032flags is optional and may be 0 or AT_REMOVEDIR. If AT_REMOVEDIR is\n\
10033specified, unlinkat() behaves like rmdir().\n\
10034If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10035is interpreted relative to the current working directory.");
10036
10037static PyObject *
10038posix_unlinkat(PyObject *self, PyObject *args)
10039{
10040 int dirfd, res, flags = 0;
10041 PyObject *opath;
10042 char *path;
10043
10044 if (!PyArg_ParseTuple(args, "iO&|i:unlinkat",
10045 &dirfd, PyUnicode_FSConverter, &opath, &flags))
10046 return NULL;
10047 path = PyBytes_AsString(opath);
10048 Py_BEGIN_ALLOW_THREADS
10049 res = unlinkat(dirfd, path, flags);
10050 Py_END_ALLOW_THREADS
10051 Py_DECREF(opath);
10052 if (res < 0)
10053 return posix_error();
10054 Py_RETURN_NONE;
10055}
10056#endif
10057
10058#ifdef HAVE_UTIMENSAT
10059PyDoc_STRVAR(posix_utimensat__doc__,
Brian Curtin569b4942011-11-07 16:09:20 -060010060"utimensat(dirfd, path[, atime=(atime_sec, atime_nsec),\n\
10061 mtime=(mtime_sec, mtime_nsec), flags=0])\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010062utimensat(dirfd, path, None, None, flags)\n\n\
10063Updates the timestamps of a file with nanosecond precision. If path is\n\
10064relative, it is taken as relative to dirfd.\n\
Brian Curtin569b4942011-11-07 16:09:20 -060010065If atime and mtime are both None, which is the default, set atime and\n\
10066mtime to the current time.\n\
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010067flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
10068If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10069is interpreted relative to the current working directory.\n\
10070If *_nsec is specified as UTIME_NOW, the timestamp is updated to the\n\
10071current time.\n\
10072If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
10073
10074static PyObject *
Brian Curtin569b4942011-11-07 16:09:20 -060010075posix_utimensat(PyObject *self, PyObject *args, PyObject *kwargs)
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010076{
10077 PyObject *opath;
10078 char *path;
10079 int res, dirfd, flags = 0;
Brian Curtin569b4942011-11-07 16:09:20 -060010080 PyObject *atime = Py_None;
10081 PyObject *mtime = Py_None;
10082
10083 static char *kwlist[] = {"dirfd", "path", "atime", "mtime", "flags", NULL};
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010084
10085 struct timespec buf[2];
10086
Brian Curtin569b4942011-11-07 16:09:20 -060010087 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|OOi:utimensat", kwlist,
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010088 &dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
10089 return NULL;
10090 path = PyBytes_AsString(opath);
10091 if (atime == Py_None && mtime == Py_None) {
10092 /* optional time values not given */
10093 Py_BEGIN_ALLOW_THREADS
10094 res = utimensat(dirfd, path, NULL, flags);
10095 Py_END_ALLOW_THREADS
10096 }
10097 else if (!PyTuple_Check(atime) || PyTuple_Size(atime) != 2) {
10098 PyErr_SetString(PyExc_TypeError,
10099 "utimensat() arg 3 must be a tuple (atime_sec, atime_nsec)");
10100 Py_DECREF(opath);
10101 return NULL;
10102 }
10103 else if (!PyTuple_Check(mtime) || PyTuple_Size(mtime) != 2) {
10104 PyErr_SetString(PyExc_TypeError,
10105 "utimensat() arg 4 must be a tuple (mtime_sec, mtime_nsec)");
10106 Py_DECREF(opath);
10107 return NULL;
10108 }
10109 else {
10110 if (!PyArg_ParseTuple(atime, "ll:utimensat",
10111 &(buf[0].tv_sec), &(buf[0].tv_nsec))) {
10112 Py_DECREF(opath);
10113 return NULL;
10114 }
10115 if (!PyArg_ParseTuple(mtime, "ll:utimensat",
10116 &(buf[1].tv_sec), &(buf[1].tv_nsec))) {
10117 Py_DECREF(opath);
10118 return NULL;
10119 }
10120 Py_BEGIN_ALLOW_THREADS
10121 res = utimensat(dirfd, path, buf, flags);
10122 Py_END_ALLOW_THREADS
10123 }
10124 Py_DECREF(opath);
10125 if (res < 0) {
10126 return posix_error();
10127 }
10128 Py_RETURN_NONE;
10129}
10130#endif
10131
10132#ifdef HAVE_MKFIFOAT
10133PyDoc_STRVAR(posix_mkfifoat__doc__,
10134"mkfifoat(dirfd, path, mode=0o666)\n\n\
10135Like mkfifo() but if path is relative, it is taken as relative to dirfd.\n\
10136If path is relative and dirfd is the special value AT_FDCWD, then path\n\
10137is interpreted relative to the current working directory.");
10138
10139static PyObject *
10140posix_mkfifoat(PyObject *self, PyObject *args)
10141{
10142 PyObject *opath;
10143 char *filename;
10144 int mode = 0666;
10145 int res, dirfd;
10146 if (!PyArg_ParseTuple(args, "iO&|i:mkfifoat",
10147 &dirfd, PyUnicode_FSConverter, &opath, &mode))
10148 return NULL;
10149 filename = PyBytes_AS_STRING(opath);
10150 Py_BEGIN_ALLOW_THREADS
10151 res = mkfifoat(dirfd, filename, mode);
10152 Py_END_ALLOW_THREADS
10153 Py_DECREF(opath);
10154 if (res < 0)
10155 return posix_error();
10156 Py_RETURN_NONE;
10157}
10158#endif
10159
Benjamin Peterson9428d532011-09-14 11:45:52 -040010160#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010161
10162static int
10163try_getxattr(const char *path, const char *name,
10164 ssize_t (*get)(const char *, const char *, void *, size_t),
10165 Py_ssize_t buf_size, PyObject **res)
10166{
10167 PyObject *value;
10168 Py_ssize_t len;
10169
10170 assert(buf_size <= XATTR_SIZE_MAX);
10171 value = PyBytes_FromStringAndSize(NULL, buf_size);
10172 if (!value)
10173 return 0;
10174 Py_BEGIN_ALLOW_THREADS;
10175 len = get(path, name, PyBytes_AS_STRING(value), buf_size);
10176 Py_END_ALLOW_THREADS;
10177 if (len < 0) {
10178 Py_DECREF(value);
10179 if (errno == ERANGE) {
10180 value = NULL;
10181 }
10182 else {
10183 posix_error();
10184 return 0;
10185 }
10186 }
10187 else if (len != buf_size) {
10188 /* Can only shrink. */
10189 _PyBytes_Resize(&value, len);
10190 }
10191 *res = value;
10192 return 1;
10193}
10194
10195static PyObject *
10196getxattr_common(const char *path, PyObject *name_obj,
10197 ssize_t (*get)(const char *, const char *, void *, size_t))
10198{
10199 PyObject *value;
10200 const char *name = PyBytes_AS_STRING(name_obj);
10201
10202 /* Try a small value first. */
10203 if (!try_getxattr(path, name, get, 128, &value))
10204 return NULL;
10205 if (value)
10206 return value;
10207 /* Now the maximum possible one. */
10208 if (!try_getxattr(path, name, get, XATTR_SIZE_MAX, &value))
10209 return NULL;
10210 assert(value);
10211 return value;
10212}
10213
10214PyDoc_STRVAR(posix_getxattr__doc__,
10215"getxattr(path, attr) -> value\n\n\
10216Return the value of extended attribute *name* on *path*.");
10217
10218static PyObject *
10219posix_getxattr(PyObject *self, PyObject *args)
10220{
10221 PyObject *path, *res, *name;
10222
10223 if (!PyArg_ParseTuple(args, "O&O&:getxattr", PyUnicode_FSConverter, &path,
10224 PyUnicode_FSConverter, &name))
10225 return NULL;
10226 res = getxattr_common(PyBytes_AS_STRING(path), name, getxattr);
10227 Py_DECREF(path);
10228 Py_DECREF(name);
10229 return res;
10230}
10231
10232PyDoc_STRVAR(posix_lgetxattr__doc__,
10233"lgetxattr(path, attr) -> value\n\n\
10234Like getxattr but don't follow symlinks.");
10235
10236static PyObject *
10237posix_lgetxattr(PyObject *self, PyObject *args)
10238{
10239 PyObject *path, *res, *name;
10240
10241 if (!PyArg_ParseTuple(args, "O&O&:lgetxattr", PyUnicode_FSConverter, &path,
10242 PyUnicode_FSConverter, &name))
10243 return NULL;
10244 res = getxattr_common(PyBytes_AS_STRING(path), name, lgetxattr);
10245 Py_DECREF(path);
10246 Py_DECREF(name);
10247 return res;
10248}
10249
10250static ssize_t
10251wrap_fgetxattr(const char *path, const char *name, void *value, size_t size)
10252{
10253 /* Hack to share code. */
10254 return fgetxattr((int)(Py_uintptr_t)path, name, value, size);
10255}
10256
10257PyDoc_STRVAR(posix_fgetxattr__doc__,
10258"fgetxattr(fd, attr) -> value\n\n\
10259Like getxattr but operate on a fd instead of a path.");
10260
10261static PyObject *
10262posix_fgetxattr(PyObject *self, PyObject *args)
10263{
10264 PyObject *res, *name;
10265 int fd;
10266
10267 if (!PyArg_ParseTuple(args, "iO&:fgetxattr", &fd, PyUnicode_FSConverter, &name))
10268 return NULL;
10269 res = getxattr_common((const char *)(Py_uintptr_t)fd, name, wrap_fgetxattr);
10270 Py_DECREF(name);
10271 return res;
10272}
10273
10274PyDoc_STRVAR(posix_setxattr__doc__,
10275"setxattr(path, attr, value, flags=0)\n\n\
10276Set extended attribute *attr* on *path* to *value*.");
10277
10278static PyObject *
10279posix_setxattr(PyObject *self, PyObject *args)
10280{
10281 PyObject *path, *name;
10282 Py_buffer data;
10283 int flags = 0, err;
10284
10285 if (!PyArg_ParseTuple(args, "O&O&y*|i:setxattr", PyUnicode_FSConverter,
10286 &path, PyUnicode_FSConverter, &name, &data, &flags))
10287 return NULL;
10288 Py_BEGIN_ALLOW_THREADS;
10289 err = setxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10290 data.buf, data.len, flags);
10291 Py_END_ALLOW_THREADS;
10292 Py_DECREF(path);
10293 Py_DECREF(name);
10294 PyBuffer_Release(&data);
10295 if (err)
10296 return posix_error();
10297 Py_RETURN_NONE;
10298}
10299
10300PyDoc_STRVAR(posix_lsetxattr__doc__,
10301"lsetxattr(path, attr, value, flags=0)\n\n\
10302Like setxattr but don't follow symlinks.");
10303
10304static PyObject *
10305posix_lsetxattr(PyObject *self, PyObject *args)
10306{
10307 PyObject *path, *name;
10308 Py_buffer data;
10309 int flags = 0, err;
10310
10311 if (!PyArg_ParseTuple(args, "O&O&y*|i:lsetxattr", PyUnicode_FSConverter,
10312 &path, PyUnicode_FSConverter, &name, &data, &flags))
10313 return NULL;
10314 Py_BEGIN_ALLOW_THREADS;
10315 err = lsetxattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name),
10316 data.buf, data.len, flags);
10317 Py_END_ALLOW_THREADS;
10318 Py_DECREF(path);
10319 Py_DECREF(name);
10320 PyBuffer_Release(&data);
10321 if (err)
10322 return posix_error();
10323 Py_RETURN_NONE;
10324}
10325
10326PyDoc_STRVAR(posix_fsetxattr__doc__,
10327"fsetxattr(fd, attr, value, flags=0)\n\n\
10328Like setxattr but operates on *fd* instead of a path.");
10329
10330static PyObject *
10331posix_fsetxattr(PyObject *self, PyObject *args)
10332{
10333 Py_buffer data;
10334 const char *name;
10335 int fd, flags = 0, err;
10336
10337 if (!PyArg_ParseTuple(args, "iO&y*|i:fsetxattr", &fd, PyUnicode_FSConverter,
10338 &name, &data, &flags))
10339 return NULL;
10340 Py_BEGIN_ALLOW_THREADS;
10341 err = fsetxattr(fd, PyBytes_AS_STRING(name), data.buf, data.len, flags);
10342 Py_END_ALLOW_THREADS;
10343 Py_DECREF(name);
10344 PyBuffer_Release(&data);
10345 if (err)
10346 return posix_error();
10347 Py_RETURN_NONE;
10348}
10349
10350PyDoc_STRVAR(posix_removexattr__doc__,
10351"removexattr(path, attr)\n\n\
10352Remove extended attribute *attr* on *path*.");
10353
10354static PyObject *
10355posix_removexattr(PyObject *self, PyObject *args)
10356{
10357 PyObject *path, *name;
10358 int err;
10359
10360 if (!PyArg_ParseTuple(args, "O&O&:removexattr", PyUnicode_FSConverter, &path,
10361 PyUnicode_FSConverter, &name))
10362 return NULL;
10363 Py_BEGIN_ALLOW_THREADS;
10364 err = removexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10365 Py_END_ALLOW_THREADS;
10366 Py_DECREF(path);
10367 Py_DECREF(name);
10368 if (err)
10369 return posix_error();
10370 Py_RETURN_NONE;
10371}
10372
10373PyDoc_STRVAR(posix_lremovexattr__doc__,
10374"lremovexattr(path, attr)\n\n\
10375Like removexattr but don't follow symlinks.");
10376
10377static PyObject *
10378posix_lremovexattr(PyObject *self, PyObject *args)
10379{
10380 PyObject *path, *name;
10381 int err;
10382
10383 if (!PyArg_ParseTuple(args, "O&O&:lremovexattr", PyUnicode_FSConverter, &path,
10384 PyUnicode_FSConverter, &name))
10385 return NULL;
10386 Py_BEGIN_ALLOW_THREADS;
10387 err = lremovexattr(PyBytes_AS_STRING(path), PyBytes_AS_STRING(name));
10388 Py_END_ALLOW_THREADS;
10389 Py_DECREF(path);
10390 Py_DECREF(name);
10391 if (err)
10392 return posix_error();
10393 Py_RETURN_NONE;
10394}
10395
10396PyDoc_STRVAR(posix_fremovexattr__doc__,
10397"fremovexattr(fd, attr)\n\n\
10398Like removexattr but operates on a file descriptor.");
10399
10400static PyObject *
10401posix_fremovexattr(PyObject *self, PyObject *args)
10402{
10403 PyObject *name;
10404 int fd, err;
10405
10406 if (!PyArg_ParseTuple(args, "iO&:fremovexattr", &fd,
10407 PyUnicode_FSConverter, &name))
10408 return NULL;
10409 Py_BEGIN_ALLOW_THREADS;
10410 err = fremovexattr(fd, PyBytes_AS_STRING(name));
10411 Py_END_ALLOW_THREADS;
10412 Py_DECREF(name);
10413 if (err)
10414 return posix_error();
10415 Py_RETURN_NONE;
10416}
10417
10418static Py_ssize_t
10419try_listxattr(const char *path, ssize_t (*list)(const char *, char *, size_t),
10420 Py_ssize_t buf_size, char **buf)
10421{
10422 Py_ssize_t len;
10423
10424 *buf = PyMem_MALLOC(buf_size);
10425 if (!*buf) {
10426 PyErr_NoMemory();
10427 return -1;
10428 }
10429 Py_BEGIN_ALLOW_THREADS;
10430 len = list(path, *buf, buf_size);
10431 Py_END_ALLOW_THREADS;
10432 if (len < 0) {
10433 PyMem_FREE(*buf);
10434 if (errno != ERANGE)
10435 posix_error();
10436 return -1;
10437 }
10438 return len;
10439}
10440
10441static PyObject *
10442listxattr_common(const char *path, ssize_t (*list)(const char *, char *, size_t))
10443{
10444 PyObject *res, *attr;
10445 Py_ssize_t len, err, start, i;
10446 char *buf;
10447
10448 len = try_listxattr(path, list, 256, &buf);
10449 if (len < 0) {
10450 if (PyErr_Occurred())
10451 return NULL;
10452 len = try_listxattr(path, list, XATTR_LIST_MAX, &buf);
10453 if (len < 0)
10454 return NULL;
10455 }
10456 res = PyList_New(0);
10457 if (!res) {
10458 PyMem_FREE(buf);
10459 return NULL;
10460 }
10461 for (start = i = 0; i < len; i++) {
10462 if (!buf[i]) {
10463 attr = PyUnicode_DecodeFSDefaultAndSize(&buf[start], i - start);
10464 if (!attr) {
10465 Py_DECREF(res);
10466 PyMem_FREE(buf);
10467 return NULL;
10468 }
10469 err = PyList_Append(res, attr);
10470 Py_DECREF(attr);
10471 if (err) {
10472 Py_DECREF(res);
10473 PyMem_FREE(buf);
10474 return NULL;
10475 }
10476 start = i + 1;
10477 }
10478 }
10479 PyMem_FREE(buf);
10480 return res;
10481}
10482
10483PyDoc_STRVAR(posix_listxattr__doc__,
10484"listxattr(path)\n\n\
10485Return a list of extended attributes on *path*.");
10486
10487static PyObject *
10488posix_listxattr(PyObject *self, PyObject *args)
10489{
10490 PyObject *path, *res;
10491
10492 if (!PyArg_ParseTuple(args, "O&:listxattr", PyUnicode_FSConverter, &path))
10493 return NULL;
10494 res = listxattr_common(PyBytes_AS_STRING(path), listxattr);
10495 Py_DECREF(path);
10496 return res;
10497}
10498
10499PyDoc_STRVAR(posix_llistxattr__doc__,
10500"llistxattr(path)\n\n\
10501Like listxattr but don't follow symlinks..");
10502
10503static PyObject *
10504posix_llistxattr(PyObject *self, PyObject *args)
10505{
10506 PyObject *path, *res;
10507
10508 if (!PyArg_ParseTuple(args, "O&:llistxattr", PyUnicode_FSConverter, &path))
10509 return NULL;
10510 res = listxattr_common(PyBytes_AS_STRING(path), llistxattr);
10511 Py_DECREF(path);
10512 return res;
10513}
10514
10515static ssize_t
10516wrap_flistxattr(const char *path, char *buf, size_t len)
10517{
10518 /* Hack to share code. */
10519 return flistxattr((int)(Py_uintptr_t)path, buf, len);
10520}
10521
10522PyDoc_STRVAR(posix_flistxattr__doc__,
10523"flistxattr(path)\n\n\
10524Like flistxattr but operates on a file descriptor.");
10525
10526static PyObject *
10527posix_flistxattr(PyObject *self, PyObject *args)
10528{
10529 long fd;
10530
10531 if (!PyArg_ParseTuple(args, "i:flistxattr", &fd))
10532 return NULL;
10533 return listxattr_common((const char *)(Py_uintptr_t)fd, wrap_flistxattr);
10534}
10535
Benjamin Peterson9428d532011-09-14 11:45:52 -040010536#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010537
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010538static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +000010539 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010540#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010541 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010542#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010543 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010544#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010545 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010546#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +000010547 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010548#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010549 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010550#endif /* HAVE_FCHMOD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010551#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010552 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010553#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +000010554#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +000010555 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010556#endif /* HAVE_LCHMOD */
10557#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010558 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +000010559#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +000010560#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +000010562#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010563#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000010564 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +000010565#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +000010566#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +000010567 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +000010568#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010569#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +000010570 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010571#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010572#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +000010573 {"getcwd", (PyCFunction)posix_getcwd_unicode,
10574 METH_NOARGS, posix_getcwd__doc__},
10575 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
10576 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010577#endif
10578#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010579 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010580#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010582#ifdef HAVE_FDOPENDIR
Charles-François Natali77940902012-02-06 19:54:48 +010010583 {"flistdir", posix_flistdir, METH_VARARGS, posix_flistdir__doc__},
Antoine Pitrou8250e232011-02-25 23:41:16 +000010584#endif
Victor Stinnerccd57152012-02-08 14:31:50 +010010585 {"lstat", (PyCFunction)posix_lstat, METH_VARARGS | METH_KEYWORDS, posix_lstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010587#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum775f4da1993-01-09 17:18:52 +000010589#endif /* HAVE_NICE */
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000010590#ifdef HAVE_GETPRIORITY
10591 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__},
10592#endif /* HAVE_GETPRIORITY */
10593#ifdef HAVE_SETPRIORITY
10594 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__},
10595#endif /* HAVE_SETPRIORITY */
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010596#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010598#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000010599#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010600 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000010601#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010602 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
Antoine Pitrouf3b2d882012-01-30 22:08:52 +010010603 {"replace", posix_replace, METH_VARARGS, posix_replace__doc__},
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +000010604 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
Victor Stinnerccd57152012-02-08 14:31:50 +010010605 {"stat", (PyCFunction)posix_stat,
10606 METH_VARARGS | METH_KEYWORDS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Brian Curtin52173d42010-12-02 18:29:18 +000010608#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossumc39de5f1992-02-05 11:15:54 +000010610#endif /* HAVE_SYMLINK */
Brian Curtin52173d42010-12-02 18:29:18 +000010611#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000010612 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
Brian Curtin52173d42010-12-02 18:29:18 +000010613 win_symlink__doc__},
10614#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossum85e3b011991-06-03 12:42:10 +000010615#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +000010616 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010617#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010618 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010619#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +000010620 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010621#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
10623 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
10624 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010625#ifdef HAVE_FUTIMES
10626 {"futimes", posix_futimes, METH_VARARGS, posix_futimes__doc__},
10627#endif
10628#ifdef HAVE_LUTIMES
10629 {"lutimes", posix_lutimes, METH_VARARGS, posix_lutimes__doc__},
10630#endif
10631#ifdef HAVE_FUTIMENS
10632 {"futimens", posix_futimens, METH_VARARGS, posix_futimens__doc__},
10633#endif
Guido van Rossum0ee42cd1991-04-08 21:01:03 +000010634#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +000010635 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010636#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010638#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
10640 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossum3b066191991-06-04 19:40:25 +000010641#endif /* HAVE_EXECV */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010642#ifdef HAVE_FEXECVE
10643 {"fexecve", posix_fexecve, METH_VARARGS, posix_fexecve__doc__},
10644#endif
Guido van Rossuma1065681999-01-25 23:20:23 +000010645#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
10647 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010648#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
10650 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +000010651#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +000010652#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010653#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +000010655#endif /* HAVE_FORK1 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010656#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +000010657 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010658#endif /* HAVE_FORK */
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010659#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010660#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010661 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__},
10662 {"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 +020010663#endif
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010664#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010665 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010666#endif
10667#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010668 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010669#endif
10670#ifdef HAVE_SCHED_RR_GET_INTERVAL
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010671 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010672#endif
10673#ifdef HAVE_SCHED_SETPARAM
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010674 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010675#endif
10676#ifdef HAVE_SCHED_SETSCHEDULER
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010677 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__},
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -050010678#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010679 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__},
Benjamin Peterson2740af82011-08-02 17:41:34 -050010680#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050010681 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__},
10682 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__},
10683#endif
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +020010684#endif /* HAVE_SCHED_H */
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010685#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +000010686 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +000010687#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +000010688#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +000010689 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +000010690#endif /* HAVE_FORKPTY */
Guido van Rossum3b066191991-06-04 19:40:25 +000010691#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010692 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +000010693#endif /* HAVE_GETEGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010694#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010695 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossum46003ff1992-05-15 11:05:24 +000010696#endif /* HAVE_GETEUID */
10697#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010698 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010699#endif /* HAVE_GETGID */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020010700#ifdef HAVE_GETGROUPLIST
10701 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
10702#endif
Fred Drakec9680921999-12-13 16:37:25 +000010703#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010704 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010705#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010706 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +000010707#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010708 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010709#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010710#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010711 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010712#endif /* HAVE_GETPPID */
10713#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010714 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010715#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +000010716#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010717 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +000010718#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +000010719#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010721#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010722#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +000010723 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +000010724#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +000010725#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010726 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +000010727#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +000010728#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010729 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
10730 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Brian Curtin1b9df392010-11-24 20:24:31 +000010731 {"link", win32_link, METH_VARARGS, win32_link__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000010732#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000010733#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010734 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010735#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010736#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010737 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010738#endif /* HAVE_SETEUID */
10739#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010741#endif /* HAVE_SETEGID */
10742#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010744#endif /* HAVE_SETREUID */
10745#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010746 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +000010747#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010748#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010749 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010750#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010751#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010752 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +000010753#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +000010754#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000010755 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000010756#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +000010757#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010758 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +000010759#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010760#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010762#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010763#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +000010765#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010766#ifdef HAVE_WAIT3
Victor Stinnerccd57152012-02-08 14:31:50 +010010767 {"wait3", (PyCFunction)posix_wait3,
10768 METH_VARARGS | METH_KEYWORDS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010769#endif /* HAVE_WAIT3 */
10770#ifdef HAVE_WAIT4
Victor Stinnerccd57152012-02-08 14:31:50 +010010771 {"wait4", (PyCFunction)posix_wait4,
10772 METH_VARARGS | METH_KEYWORDS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010773#endif /* HAVE_WAIT4 */
Ross Lagerwall7807c352011-03-17 20:20:30 +020010774#if defined(HAVE_WAITID) && !defined(__APPLE__)
10775 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__},
10776#endif
Tim Petersab034fa2002-02-01 11:27:43 +000010777#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +000010778 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010779#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010780#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +000010782#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010783#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010785#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010786#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010788#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010789#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010791#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +000010792#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +000010793 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000010794#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +000010795 {"open", posix_open, METH_VARARGS, posix_open__doc__},
10796 {"close", posix_close, METH_VARARGS, posix_close__doc__},
10797 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
10798 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
10799 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
10800 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010801#ifdef HAVE_LOCKF
10802 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__},
10803#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010804 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
10805 {"read", posix_read, METH_VARARGS, posix_read__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010806#ifdef HAVE_READV
10807 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__},
10808#endif
10809#ifdef HAVE_PREAD
10810 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__},
10811#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010812 {"write", posix_write, METH_VARARGS, posix_write__doc__},
Ross Lagerwall7807c352011-03-17 20:20:30 +020010813#ifdef HAVE_WRITEV
10814 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__},
10815#endif
10816#ifdef HAVE_PWRITE
10817 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__},
10818#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000010819#ifdef HAVE_SENDFILE
10820 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
10821 posix_sendfile__doc__},
10822#endif
Victor Stinnerccd57152012-02-08 14:31:50 +010010823 {"fstat", (PyCFunction)posix_fstat, METH_VARARGS | METH_KEYWORDS,
10824 posix_fstat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000010825 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010826#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010827 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010828#endif
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010829#ifdef HAVE_PIPE2
Charles-François Natali368f34b2011-06-06 19:49:47 +020010830 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__},
Charles-François Natalidaafdd52011-05-29 20:07:40 +020010831#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010832#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +000010833 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010834#endif
Neal Norwitz11690112002-07-30 01:08:28 +000010835#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +000010836 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +000010837#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010838#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +000010839 {"major", posix_major, METH_VARARGS, posix_major__doc__},
10840 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
10841 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +000010842#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010843#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +000010844 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +000010845#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010846#ifdef HAVE_TRUNCATE
10847 {"truncate", posix_truncate, METH_VARARGS, posix_truncate__doc__},
10848#endif
10849#ifdef HAVE_POSIX_FALLOCATE
10850 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__},
10851#endif
10852#ifdef HAVE_POSIX_FADVISE
10853 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__},
10854#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010855#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010856 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +000010857#endif
Guido van Rossumc524d952001-10-19 01:31:59 +000010858#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +000010859 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +000010860#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010861 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010862#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +000010863 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +000010864#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010865#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010866 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010867#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +020010868#ifdef HAVE_SYNC
10869 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__},
10870#endif
Guido van Rossum21142a01999-01-08 21:05:37 +000010871#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010872 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +000010873#endif
Guido van Rossumc9641791998-08-04 15:26:23 +000010874#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +000010875#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +000010876 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +000010877#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010878#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000010879 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +000010880#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +000010881#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +000010882 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010883#endif /* WIFSTOPPED */
10884#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +000010885 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010886#endif /* WIFSIGNALED */
10887#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +000010888 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010889#endif /* WIFEXITED */
10890#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +000010891 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010892#endif /* WEXITSTATUS */
10893#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010894 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010895#endif /* WTERMSIG */
10896#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010897 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +000010898#endif /* WSTOPSIG */
10899#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +000010900#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010901 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010902#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000010903#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +000010904 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +000010905#endif
Fred Drakec9680921999-12-13 16:37:25 +000010906#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +000010907 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010908#endif
10909#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010910 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010911#endif
10912#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010913 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010914#endif
10915#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010916 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +000010917#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000010918 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010919#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010920 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +000010921 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +000010922 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050010923 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +020010924 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000010925#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +000010926#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +000010927 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +000010928#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010929 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000010930 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +000010931 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010932 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +000010933 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +000010934 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010935#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010936 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010937#endif
10938#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010939 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010940#endif
10941#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +000010942 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010943#endif
10944#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +000010945 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010946#endif
10947
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010948/* posix *at family of functions */
10949#ifdef HAVE_FACCESSAT
10950 {"faccessat", posix_faccessat, METH_VARARGS, posix_faccessat__doc__},
10951#endif
10952#ifdef HAVE_FCHMODAT
10953 {"fchmodat", posix_fchmodat, METH_VARARGS, posix_fchmodat__doc__},
10954#endif /* HAVE_FCHMODAT */
10955#ifdef HAVE_FCHOWNAT
10956 {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__},
10957#endif /* HAVE_FCHOWNAT */
10958#ifdef HAVE_FSTATAT
Victor Stinnerccd57152012-02-08 14:31:50 +010010959 {"fstatat", (PyCFunction)posix_fstatat, METH_VARARGS | METH_KEYWORDS,
10960 posix_fstatat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010961#endif
10962#ifdef HAVE_FUTIMESAT
10963 {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__},
10964#endif
10965#ifdef HAVE_LINKAT
10966 {"linkat", posix_linkat, METH_VARARGS, posix_linkat__doc__},
10967#endif /* HAVE_LINKAT */
10968#ifdef HAVE_MKDIRAT
10969 {"mkdirat", posix_mkdirat, METH_VARARGS, posix_mkdirat__doc__},
10970#endif
10971#if defined(HAVE_MKNODAT) && defined(HAVE_MAKEDEV)
10972 {"mknodat", posix_mknodat, METH_VARARGS, posix_mknodat__doc__},
10973#endif
10974#ifdef HAVE_OPENAT
10975 {"openat", posix_openat, METH_VARARGS, posix_openat__doc__},
10976#endif
10977#ifdef HAVE_READLINKAT
10978 {"readlinkat", posix_readlinkat, METH_VARARGS, posix_readlinkat__doc__},
10979#endif /* HAVE_READLINKAT */
10980#ifdef HAVE_RENAMEAT
10981 {"renameat", posix_renameat, METH_VARARGS, posix_renameat__doc__},
10982#endif
10983#if HAVE_SYMLINKAT
10984 {"symlinkat", posix_symlinkat, METH_VARARGS, posix_symlinkat__doc__},
10985#endif /* HAVE_SYMLINKAT */
10986#ifdef HAVE_UNLINKAT
10987 {"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
10988#endif
10989#ifdef HAVE_UTIMENSAT
Jesus Cead03a4912011-11-08 17:28:04 +010010990 {"utimensat", (PyCFunction)posix_utimensat,
10991 METH_VARARGS | METH_KEYWORDS,
Brian Curtin569b4942011-11-07 16:09:20 -060010992 posix_utimensat__doc__},
Antoine Pitrouf65132d2011-02-25 23:25:17 +000010993#endif
10994#ifdef HAVE_MKFIFOAT
10995 {"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},
10996#endif
Benjamin Peterson9428d532011-09-14 11:45:52 -040010997#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040010998 {"setxattr", posix_setxattr, METH_VARARGS, posix_setxattr__doc__},
10999 {"lsetxattr", posix_lsetxattr, METH_VARARGS, posix_lsetxattr__doc__},
11000 {"fsetxattr", posix_fsetxattr, METH_VARARGS, posix_fsetxattr__doc__},
11001 {"getxattr", posix_getxattr, METH_VARARGS, posix_getxattr__doc__},
11002 {"lgetxattr", posix_lgetxattr, METH_VARARGS, posix_lgetxattr__doc__},
11003 {"fgetxattr", posix_fgetxattr, METH_VARARGS, posix_fgetxattr__doc__},
11004 {"removexattr", posix_removexattr, METH_VARARGS, posix_removexattr__doc__},
11005 {"lremovexattr", posix_lremovexattr, METH_VARARGS, posix_lremovexattr__doc__},
11006 {"fremovexattr", posix_fremovexattr, METH_VARARGS, posix_fremovexattr__doc__},
11007 {"listxattr", posix_listxattr, METH_VARARGS, posix_listxattr__doc__},
11008 {"llistxattr", posix_llistxattr, METH_VARARGS, posix_llistxattr__doc__},
11009 {"flistxattr", posix_flistxattr, METH_VARARGS, posix_flistxattr__doc__},
11010#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011011 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011012};
11013
11014
Barry Warsaw4a342091996-12-19 23:50:02 +000011015static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000011016ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +000011017{
Victor Stinner8c62be82010-05-06 00:08:46 +000011018 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +000011019}
11020
Guido van Rossumd48f2521997-12-05 22:19:34 +000011021#if defined(PYOS_OS2)
11022/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011023static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011024{
11025 APIRET rc;
11026 ULONG values[QSV_MAX+1];
11027 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +000011028 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +000011029
11030 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +000011031 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011032 Py_END_ALLOW_THREADS
11033
11034 if (rc != NO_ERROR) {
11035 os2_error(rc);
11036 return -1;
11037 }
11038
Fred Drake4d1e64b2002-04-15 19:40:07 +000011039 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
11040 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
11041 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
11042 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
11043 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
11044 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
11045 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011046
11047 switch (values[QSV_VERSION_MINOR]) {
11048 case 0: ver = "2.00"; break;
11049 case 10: ver = "2.10"; break;
11050 case 11: ver = "2.11"; break;
11051 case 30: ver = "3.00"; break;
11052 case 40: ver = "4.00"; break;
11053 case 50: ver = "5.00"; break;
11054 default:
Tim Peters885d4572001-11-28 20:27:42 +000011055 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +000011056 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +000011057 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011058 ver = &tmp[0];
11059 }
11060
11061 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +000011062 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +000011063 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011064
11065 /* Add Indicator of Which Drive was Used to Boot the System */
11066 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
11067 tmp[1] = ':';
11068 tmp[2] = '\0';
11069
Fred Drake4d1e64b2002-04-15 19:40:07 +000011070 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +000011071}
11072#endif
11073
Brian Curtin52173d42010-12-02 18:29:18 +000011074#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011075static int
Brian Curtin52173d42010-12-02 18:29:18 +000011076enable_symlink()
11077{
11078 HANDLE tok;
11079 TOKEN_PRIVILEGES tok_priv;
11080 LUID luid;
11081 int meth_idx = 0;
11082
11083 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011084 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011085
11086 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011087 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011088
11089 tok_priv.PrivilegeCount = 1;
11090 tok_priv.Privileges[0].Luid = luid;
11091 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
11092
11093 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
11094 sizeof(TOKEN_PRIVILEGES),
11095 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000011096 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000011097
Brian Curtin3b4499c2010-12-28 14:31:47 +000011098 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
11099 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000011100}
11101#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
11102
Barry Warsaw4a342091996-12-19 23:50:02 +000011103static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011104all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +000011105{
Guido van Rossum94f6f721999-01-06 18:42:14 +000011106#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011107 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011108#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011109#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011110 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011111#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011112#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011113 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011114#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000011115#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011116 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011117#endif
Fred Drakec9680921999-12-13 16:37:25 +000011118#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011119 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000011120#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011121#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000011122 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000011123#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011124#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +000011125 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011126#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011127#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +000011128 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011129#endif
Fred Drake106c1a02002-04-23 15:58:02 +000011130#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +000011131 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000011132#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000011133#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011134 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011135#endif
11136#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +000011137 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011138#endif
11139#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +000011140 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011141#endif
11142#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +000011143 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011144#endif
11145#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011146 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011147#endif
11148#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +000011149 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011150#endif
11151#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011152 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011153#endif
11154#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011155 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011156#endif
11157#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011158 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011159#endif
11160#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +000011161 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011162#endif
11163#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011164 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011165#endif
11166#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +000011167 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011168#endif
11169#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011170 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000011171#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000011172#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011173 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011174#endif
11175#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +000011176 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000011177#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011178#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011179 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011180#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000011181#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011182 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011183#endif
11184#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000011185 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000011186#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011187#ifdef PRIO_PROCESS
11188 if (ins(d, "PRIO_PROCESS", (long)PRIO_PROCESS)) return -1;
11189#endif
11190#ifdef PRIO_PGRP
11191 if (ins(d, "PRIO_PGRP", (long)PRIO_PGRP)) return -1;
11192#endif
11193#ifdef PRIO_USER
11194 if (ins(d, "PRIO_USER", (long)PRIO_USER)) return -1;
11195#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020011196#ifdef O_CLOEXEC
11197 if (ins(d, "O_CLOEXEC", (long)O_CLOEXEC)) return -1;
11198#endif
Antoine Pitrouf65132d2011-02-25 23:25:17 +000011199/* posix - constants for *at functions */
11200#ifdef AT_SYMLINK_NOFOLLOW
11201 if (ins(d, "AT_SYMLINK_NOFOLLOW", (long)AT_SYMLINK_NOFOLLOW)) return -1;
11202#endif
11203#ifdef AT_EACCESS
11204 if (ins(d, "AT_EACCESS", (long)AT_EACCESS)) return -1;
11205#endif
11206#ifdef AT_FDCWD
11207 if (ins(d, "AT_FDCWD", (long)AT_FDCWD)) return -1;
11208#endif
11209#ifdef AT_REMOVEDIR
11210 if (ins(d, "AT_REMOVEDIR", (long)AT_REMOVEDIR)) return -1;
11211#endif
11212#ifdef AT_SYMLINK_FOLLOW
11213 if (ins(d, "AT_SYMLINK_FOLLOW", (long)AT_SYMLINK_FOLLOW)) return -1;
11214#endif
11215#ifdef UTIME_NOW
11216 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11217#endif
11218#ifdef UTIME_OMIT
11219 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11220#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000011221
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011222
Tim Peters5aa91602002-01-30 05:46:57 +000011223/* MS Windows */
11224#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000011225 /* Don't inherit in child processes. */
11226 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011227#endif
11228#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000011229 /* Optimize for short life (keep in memory). */
11230 /* MS forgot to define this one with a non-underscore form too. */
11231 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011232#endif
11233#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000011234 /* Automatically delete when last handle is closed. */
11235 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011236#endif
11237#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000011238 /* Optimize for random access. */
11239 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011240#endif
11241#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000011242 /* Optimize for sequential access. */
11243 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000011244#endif
11245
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011246/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011247#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000011248 /* Send a SIGIO signal whenever input or output
11249 becomes available on file descriptor */
11250 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000011251#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011252#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000011253 /* Direct disk access. */
11254 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011255#endif
11256#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000011257 /* Must be a directory. */
11258 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011259#endif
11260#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000011261 /* Do not follow links. */
11262 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000011263#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011264#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000011265 /* Do not update the access time. */
11266 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000011267#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000011268
Victor Stinner8c62be82010-05-06 00:08:46 +000011269 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011270#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +000011271 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011272#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011273#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +000011274 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011275#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011276#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011277 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011278#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011279#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +000011280 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011281#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011282#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +000011283 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011284#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011285#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +000011286 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011287#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011288#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +000011289 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011290#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011291#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +000011292 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011293#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011294#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011295 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011296#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011297#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +000011298 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011299#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011300#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +000011301 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011302#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011303#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +000011304 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011305#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011306#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +000011307 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011308#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011309#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +000011310 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011311#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011312#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +000011313 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011314#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011315#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +000011316 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011317#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011318#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +000011319 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000011320#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000011321
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011322 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011323#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011324 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011325#endif /* ST_RDONLY */
11326#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000011327 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000011328#endif /* ST_NOSUID */
11329
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000011330 /* FreeBSD sendfile() constants */
11331#ifdef SF_NODISKIO
11332 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1;
11333#endif
11334#ifdef SF_MNOWAIT
11335 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1;
11336#endif
11337#ifdef SF_SYNC
11338 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1;
11339#endif
11340
Ross Lagerwall7807c352011-03-17 20:20:30 +020011341 /* constants for posix_fadvise */
11342#ifdef POSIX_FADV_NORMAL
11343 if (ins(d, "POSIX_FADV_NORMAL", (long)POSIX_FADV_NORMAL)) return -1;
11344#endif
11345#ifdef POSIX_FADV_SEQUENTIAL
11346 if (ins(d, "POSIX_FADV_SEQUENTIAL", (long)POSIX_FADV_SEQUENTIAL)) return -1;
11347#endif
11348#ifdef POSIX_FADV_RANDOM
11349 if (ins(d, "POSIX_FADV_RANDOM", (long)POSIX_FADV_RANDOM)) return -1;
11350#endif
11351#ifdef POSIX_FADV_NOREUSE
11352 if (ins(d, "POSIX_FADV_NOREUSE", (long)POSIX_FADV_NOREUSE)) return -1;
11353#endif
11354#ifdef POSIX_FADV_WILLNEED
11355 if (ins(d, "POSIX_FADV_WILLNEED", (long)POSIX_FADV_WILLNEED)) return -1;
11356#endif
11357#ifdef POSIX_FADV_DONTNEED
11358 if (ins(d, "POSIX_FADV_DONTNEED", (long)POSIX_FADV_DONTNEED)) return -1;
11359#endif
11360
11361 /* constants for waitid */
11362#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
11363 if (ins(d, "P_PID", (long)P_PID)) return -1;
11364 if (ins(d, "P_PGID", (long)P_PGID)) return -1;
11365 if (ins(d, "P_ALL", (long)P_ALL)) return -1;
11366#endif
11367#ifdef WEXITED
11368 if (ins(d, "WEXITED", (long)WEXITED)) return -1;
11369#endif
11370#ifdef WNOWAIT
11371 if (ins(d, "WNOWAIT", (long)WNOWAIT)) return -1;
11372#endif
11373#ifdef WSTOPPED
11374 if (ins(d, "WSTOPPED", (long)WSTOPPED)) return -1;
11375#endif
11376#ifdef CLD_EXITED
11377 if (ins(d, "CLD_EXITED", (long)CLD_EXITED)) return -1;
11378#endif
11379#ifdef CLD_DUMPED
11380 if (ins(d, "CLD_DUMPED", (long)CLD_DUMPED)) return -1;
11381#endif
11382#ifdef CLD_TRAPPED
11383 if (ins(d, "CLD_TRAPPED", (long)CLD_TRAPPED)) return -1;
11384#endif
11385#ifdef CLD_CONTINUED
11386 if (ins(d, "CLD_CONTINUED", (long)CLD_CONTINUED)) return -1;
11387#endif
11388
11389 /* constants for lockf */
11390#ifdef F_LOCK
11391 if (ins(d, "F_LOCK", (long)F_LOCK)) return -1;
11392#endif
11393#ifdef F_TLOCK
11394 if (ins(d, "F_TLOCK", (long)F_TLOCK)) return -1;
11395#endif
11396#ifdef F_ULOCK
11397 if (ins(d, "F_ULOCK", (long)F_ULOCK)) return -1;
11398#endif
11399#ifdef F_TEST
11400 if (ins(d, "F_TEST", (long)F_TEST)) return -1;
11401#endif
11402
11403 /* constants for futimens */
11404#ifdef UTIME_NOW
11405 if (ins(d, "UTIME_NOW", (long)UTIME_NOW)) return -1;
11406#endif
11407#ifdef UTIME_OMIT
11408 if (ins(d, "UTIME_OMIT", (long)UTIME_OMIT)) return -1;
11409#endif
11410
Guido van Rossum246bc171999-02-01 23:54:31 +000011411#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011412#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +000011413 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
11414 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
11415 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
11416 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
11417 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
11418 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
11419 if (ins(d, "P_PM", (long)P_PM)) return -1;
11420 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
11421 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
11422 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
11423 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
11424 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
11425 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
11426 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
11427 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
11428 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
11429 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
11430 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
11431 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
11432 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011433#else
Victor Stinner8c62be82010-05-06 00:08:46 +000011434 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
11435 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
11436 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
11437 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
11438 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000011439#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000011440#endif
Guido van Rossum246bc171999-02-01 23:54:31 +000011441
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011442#ifdef HAVE_SCHED_H
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011443 if (ins(d, "SCHED_OTHER", (long)SCHED_OTHER)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011444 if (ins(d, "SCHED_FIFO", (long)SCHED_FIFO)) return -1;
11445 if (ins(d, "SCHED_RR", (long)SCHED_RR)) return -1;
11446#ifdef SCHED_SPORADIC
11447 if (ins(d, "SCHED_SPORADIC", (long)SCHED_SPORADIC) return -1;
11448#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011449#ifdef SCHED_BATCH
11450 if (ins(d, "SCHED_BATCH", (long)SCHED_BATCH)) return -1;
11451#endif
11452#ifdef SCHED_IDLE
11453 if (ins(d, "SCHED_IDLE", (long)SCHED_IDLE)) return -1;
11454#endif
11455#ifdef SCHED_RESET_ON_FORK
11456 if (ins(d, "SCHED_RESET_ON_FORK", (long)SCHED_RESET_ON_FORK)) return -1;
11457#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020011458#ifdef SCHED_SYS
11459 if (ins(d, "SCHED_SYS", (long)SCHED_SYS)) return -1;
11460#endif
11461#ifdef SCHED_IA
11462 if (ins(d, "SCHED_IA", (long)SCHED_IA)) return -1;
11463#endif
11464#ifdef SCHED_FSS
11465 if (ins(d, "SCHED_FSS", (long)SCHED_FSS)) return -1;
11466#endif
11467#ifdef SCHED_FX
11468 if (ins(d, "SCHED_FX", (long)SCHED_FSS)) return -1;
11469#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011470#endif
11471
Benjamin Peterson9428d532011-09-14 11:45:52 -040011472#ifdef USE_XATTRS
Benjamin Peterson799bd802011-08-31 22:15:17 -040011473 if (ins(d, "XATTR_CREATE", (long)XATTR_CREATE)) return -1;
11474 if (ins(d, "XATTR_REPLACE", (long)XATTR_REPLACE)) return -1;
11475 if (ins(d, "XATTR_SIZE_MAX", (long)XATTR_SIZE_MAX)) return -1;
11476#endif
11477
Victor Stinner8b905bd2011-10-25 13:34:04 +020011478#ifdef RTLD_LAZY
11479 if (PyModule_AddIntMacro(d, RTLD_LAZY)) return -1;
11480#endif
11481#ifdef RTLD_NOW
11482 if (PyModule_AddIntMacro(d, RTLD_NOW)) return -1;
11483#endif
11484#ifdef RTLD_GLOBAL
11485 if (PyModule_AddIntMacro(d, RTLD_GLOBAL)) return -1;
11486#endif
11487#ifdef RTLD_LOCAL
11488 if (PyModule_AddIntMacro(d, RTLD_LOCAL)) return -1;
11489#endif
11490#ifdef RTLD_NODELETE
11491 if (PyModule_AddIntMacro(d, RTLD_NODELETE)) return -1;
11492#endif
11493#ifdef RTLD_NOLOAD
11494 if (PyModule_AddIntMacro(d, RTLD_NOLOAD)) return -1;
11495#endif
11496#ifdef RTLD_DEEPBIND
11497 if (PyModule_AddIntMacro(d, RTLD_DEEPBIND)) return -1;
11498#endif
11499
Guido van Rossumd48f2521997-12-05 22:19:34 +000011500#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +000011501 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +000011502#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011503 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000011504}
11505
11506
Tim Peters5aa91602002-01-30 05:46:57 +000011507#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011508#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011509#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011510
11511#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +000011512#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011513#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +000011514
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000011515#else
Martin v. Löwis1a214512008-06-11 05:26:20 +000011516#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +000011517#define MODNAME "posix"
11518#endif
11519
Martin v. Löwis1a214512008-06-11 05:26:20 +000011520static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000011521 PyModuleDef_HEAD_INIT,
11522 MODNAME,
11523 posix__doc__,
11524 -1,
11525 posix_methods,
11526 NULL,
11527 NULL,
11528 NULL,
11529 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000011530};
11531
11532
Mark Hammondfe51c6d2002-08-02 02:27:13 +000011533PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000011534INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000011535{
Victor Stinner8c62be82010-05-06 00:08:46 +000011536 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +000011537
Brian Curtin52173d42010-12-02 18:29:18 +000011538#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000011539 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000011540#endif
11541
Victor Stinner8c62be82010-05-06 00:08:46 +000011542 m = PyModule_Create(&posixmodule);
11543 if (m == NULL)
11544 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000011545
Victor Stinner8c62be82010-05-06 00:08:46 +000011546 /* Initialize environ dictionary */
11547 v = convertenviron();
11548 Py_XINCREF(v);
11549 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
11550 return NULL;
11551 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000011552
Victor Stinner8c62be82010-05-06 00:08:46 +000011553 if (all_ins(m))
11554 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000011555
Victor Stinner8c62be82010-05-06 00:08:46 +000011556 if (setup_confname_tables(m))
11557 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000011558
Victor Stinner8c62be82010-05-06 00:08:46 +000011559 Py_INCREF(PyExc_OSError);
11560 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000011561
Benjamin Peterson2740af82011-08-02 17:41:34 -050011562#ifdef HAVE_SCHED_SETAFFINITY
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011563 if (PyType_Ready(&cpu_set_type) < 0)
11564 return NULL;
11565 Py_INCREF(&cpu_set_type);
11566 PyModule_AddObject(m, "cpu_set", (PyObject *)&cpu_set_type);
Benjamin Peterson2740af82011-08-02 17:41:34 -050011567#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011568
Guido van Rossumb3d39562000-01-31 18:41:26 +000011569#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000011570 if (posix_putenv_garbage == NULL)
11571 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000011572#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000011573
Victor Stinner8c62be82010-05-06 00:08:46 +000011574 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020011575#if defined(HAVE_WAITID) && !defined(__APPLE__)
11576 waitid_result_desc.name = MODNAME ".waitid_result";
11577 PyStructSequence_InitType(&WaitidResultType, &waitid_result_desc);
11578#endif
11579
Victor Stinner8c62be82010-05-06 00:08:46 +000011580 stat_result_desc.name = MODNAME ".stat_result";
11581 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
11582 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
11583 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
11584 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
11585 structseq_new = StatResultType.tp_new;
11586 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011587
Victor Stinner8c62be82010-05-06 00:08:46 +000011588 statvfs_result_desc.name = MODNAME ".statvfs_result";
11589 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011590#ifdef NEED_TICKS_PER_SECOND
11591# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000011592 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011593# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000011594 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011595# else
Victor Stinner8c62be82010-05-06 00:08:46 +000011596 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000011597# endif
11598#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011599
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050011600#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011601 sched_param_desc.name = MODNAME ".sched_param";
11602 PyStructSequence_InitType(&SchedParamType, &sched_param_desc);
11603 SchedParamType.tp_new = sched_param_new;
11604#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011605 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020011606#if defined(HAVE_WAITID) && !defined(__APPLE__)
11607 Py_INCREF((PyObject*) &WaitidResultType);
11608 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
11609#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011610 Py_INCREF((PyObject*) &StatResultType);
11611 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
11612 Py_INCREF((PyObject*) &StatVFSResultType);
11613 PyModule_AddObject(m, "statvfs_result",
11614 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011615
11616#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050011617 Py_INCREF(&SchedParamType);
11618 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050011619#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000011620 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011621
11622#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000011623 /*
11624 * Step 2 of weak-linking support on Mac OS X.
11625 *
11626 * The code below removes functions that are not available on the
11627 * currently active platform.
11628 *
11629 * This block allow one to use a python binary that was build on
11630 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
11631 * OSX 10.4.
11632 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000011633#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011634 if (fstatvfs == NULL) {
11635 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
11636 return NULL;
11637 }
11638 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011639#endif /* HAVE_FSTATVFS */
11640
11641#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000011642 if (statvfs == NULL) {
11643 if (PyObject_DelAttrString(m, "statvfs") == -1) {
11644 return NULL;
11645 }
11646 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011647#endif /* HAVE_STATVFS */
11648
11649# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000011650 if (lchown == NULL) {
11651 if (PyObject_DelAttrString(m, "lchown") == -1) {
11652 return NULL;
11653 }
11654 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000011655#endif /* HAVE_LCHOWN */
11656
11657
11658#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +000011659 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +000011660
Guido van Rossumb6775db1994-08-01 11:34:53 +000011661}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011662
11663#ifdef __cplusplus
11664}
11665#endif